ActivityManagerService.java revision 6e051cc2c3fe3f7186930792dcd8e1a04b78a311
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 = 256 * 1024;
508
509    // Access modes for handleIncomingUser.
510    static final int ALLOW_NON_FULL = 0;
511    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
512    static final int ALLOW_FULL_ONLY = 2;
513
514    // Delay in notifying task stack change listeners (in millis)
515    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
516
517    // Necessary ApplicationInfo flags to mark an app as persistent
518    private static final int PERSISTENT_MASK =
519            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
520
521    // Intent sent when remote bugreport collection has been completed
522    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
523            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
524
525    // Delay to disable app launch boost
526    static final int APP_BOOST_MESSAGE_DELAY = 3000;
527    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
528    static final int APP_BOOST_TIMEOUT = 2500;
529
530    // Used to indicate that a task is removed it should also be removed from recents.
531    private static final boolean REMOVE_FROM_RECENTS = true;
532    // Used to indicate that an app transition should be animated.
533    static final boolean ANIMATE = true;
534
535    // Determines whether to take full screen screenshots
536    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
537    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
538
539    private static native int nativeMigrateToBoost();
540    private static native int nativeMigrateFromBoost();
541    private boolean mIsBoosted = false;
542    private long mBoostStartTime = 0;
543
544    /** All system services */
545    SystemServiceManager mSystemServiceManager;
546
547    private Installer mInstaller;
548
549    /** Run all ActivityStacks through this */
550    final ActivityStackSupervisor mStackSupervisor;
551
552    final ActivityStarter mActivityStarter;
553
554    /** Task stack change listeners. */
555    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
556            new RemoteCallbackList<ITaskStackListener>();
557
558    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
559
560    public IntentFirewall mIntentFirewall;
561
562    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
563    // default actuion automatically.  Important for devices without direct input
564    // devices.
565    private boolean mShowDialogs = true;
566    private boolean mInVrMode = false;
567
568    BroadcastQueue mFgBroadcastQueue;
569    BroadcastQueue mBgBroadcastQueue;
570    // Convenient for easy iteration over the queues. Foreground is first
571    // so that dispatch of foreground broadcasts gets precedence.
572    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
573
574    BroadcastStats mLastBroadcastStats;
575    BroadcastStats mCurBroadcastStats;
576
577    BroadcastQueue broadcastQueueForIntent(Intent intent) {
578        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
579        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
580                "Broadcast intent " + intent + " on "
581                + (isFg ? "foreground" : "background") + " queue");
582        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
583    }
584
585    /**
586     * Activity we have told the window manager to have key focus.
587     */
588    ActivityRecord mFocusedActivity = null;
589
590    /**
591     * User id of the last activity mFocusedActivity was set to.
592     */
593    private int mLastFocusedUserId;
594
595    /**
596     * If non-null, we are tracking the time the user spends in the currently focused app.
597     */
598    private AppTimeTracker mCurAppTimeTracker;
599
600    /**
601     * List of intents that were used to start the most recent tasks.
602     */
603    final RecentTasks mRecentTasks;
604
605    /**
606     * For addAppTask: cached of the last activity component that was added.
607     */
608    ComponentName mLastAddedTaskComponent;
609
610    /**
611     * For addAppTask: cached of the last activity uid that was added.
612     */
613    int mLastAddedTaskUid;
614
615    /**
616     * For addAppTask: cached of the last ActivityInfo that was added.
617     */
618    ActivityInfo mLastAddedTaskActivity;
619
620    /**
621     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
622     */
623    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
624
625    /**
626     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
627     */
628    String mDeviceOwnerName;
629
630    final UserController mUserController;
631
632    final AppErrors mAppErrors;
633
634    boolean mDoingSetFocusedActivity;
635
636    public boolean canShowErrorDialogs() {
637        return mShowDialogs && !mSleeping && !mShuttingDown;
638    }
639
640    // it's a semaphore; boost when 0->1, reset when 1->0
641    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
642        @Override protected Integer initialValue() {
643            return 0;
644        }
645    };
646
647    static void boostPriorityForLockedSection() {
648        if (sIsBoosted.get() == 0) {
649            // boost to prio 118 while holding a global lock
650            Process.setThreadPriority(Process.myTid(), -2);
651            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
652        }
653        int cur = sIsBoosted.get();
654        sIsBoosted.set(cur + 1);
655    }
656
657    static void resetPriorityAfterLockedSection() {
658        sIsBoosted.set(sIsBoosted.get() - 1);
659        if (sIsBoosted.get() == 0) {
660            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
661            Process.setThreadPriority(Process.myTid(), 0);
662        }
663    }
664    public class PendingAssistExtras extends Binder implements Runnable {
665        public final ActivityRecord activity;
666        public final Bundle extras;
667        public final Intent intent;
668        public final String hint;
669        public final IResultReceiver receiver;
670        public final int userHandle;
671        public boolean haveResult = false;
672        public Bundle result = null;
673        public AssistStructure structure = null;
674        public AssistContent content = null;
675        public Bundle receiverExtras;
676
677        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
678                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
679            activity = _activity;
680            extras = _extras;
681            intent = _intent;
682            hint = _hint;
683            receiver = _receiver;
684            receiverExtras = _receiverExtras;
685            userHandle = _userHandle;
686        }
687        @Override
688        public void run() {
689            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
690            synchronized (this) {
691                haveResult = true;
692                notifyAll();
693            }
694            pendingAssistExtrasTimedOut(this);
695        }
696    }
697
698    final ArrayList<PendingAssistExtras> mPendingAssistExtras
699            = new ArrayList<PendingAssistExtras>();
700
701    /**
702     * Process management.
703     */
704    final ProcessList mProcessList = new ProcessList();
705
706    /**
707     * All of the applications we currently have running organized by name.
708     * The keys are strings of the application package name (as
709     * returned by the package manager), and the keys are ApplicationRecord
710     * objects.
711     */
712    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
713
714    /**
715     * Tracking long-term execution of processes to look for abuse and other
716     * bad app behavior.
717     */
718    final ProcessStatsService mProcessStats;
719
720    /**
721     * The currently running isolated processes.
722     */
723    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
724
725    /**
726     * Counter for assigning isolated process uids, to avoid frequently reusing the
727     * same ones.
728     */
729    int mNextIsolatedProcessUid = 0;
730
731    /**
732     * The currently running heavy-weight process, if any.
733     */
734    ProcessRecord mHeavyWeightProcess = null;
735
736    /**
737     * All of the processes we currently have running organized by pid.
738     * The keys are the pid running the application.
739     *
740     * <p>NOTE: This object is protected by its own lock, NOT the global
741     * activity manager lock!
742     */
743    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
744
745    /**
746     * All of the processes that have been forced to be foreground.  The key
747     * is the pid of the caller who requested it (we hold a death
748     * link on it).
749     */
750    abstract class ForegroundToken implements IBinder.DeathRecipient {
751        int pid;
752        IBinder token;
753    }
754    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
755
756    /**
757     * List of records for processes that someone had tried to start before the
758     * system was ready.  We don't start them at that point, but ensure they
759     * are started by the time booting is complete.
760     */
761    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
762
763    /**
764     * List of persistent applications that are in the process
765     * of being started.
766     */
767    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
768
769    /**
770     * Processes that are being forcibly torn down.
771     */
772    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
773
774    /**
775     * List of running applications, sorted by recent usage.
776     * The first entry in the list is the least recently used.
777     */
778    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
779
780    /**
781     * Where in mLruProcesses that the processes hosting activities start.
782     */
783    int mLruProcessActivityStart = 0;
784
785    /**
786     * Where in mLruProcesses that the processes hosting services start.
787     * This is after (lower index) than mLruProcessesActivityStart.
788     */
789    int mLruProcessServiceStart = 0;
790
791    /**
792     * List of processes that should gc as soon as things are idle.
793     */
794    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
795
796    /**
797     * Processes we want to collect PSS data from.
798     */
799    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
800
801    private boolean mBinderTransactionTrackingEnabled = false;
802
803    /**
804     * Last time we requested PSS data of all processes.
805     */
806    long mLastFullPssTime = SystemClock.uptimeMillis();
807
808    /**
809     * If set, the next time we collect PSS data we should do a full collection
810     * with data from native processes and the kernel.
811     */
812    boolean mFullPssPending = false;
813
814    /**
815     * This is the process holding what we currently consider to be
816     * the "home" activity.
817     */
818    ProcessRecord mHomeProcess;
819
820    /**
821     * This is the process holding the activity the user last visited that
822     * is in a different process from the one they are currently in.
823     */
824    ProcessRecord mPreviousProcess;
825
826    /**
827     * The time at which the previous process was last visible.
828     */
829    long mPreviousProcessVisibleTime;
830
831    /**
832     * Track all uids that have actively running processes.
833     */
834    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
835
836    /**
837     * This is for verifying the UID report flow.
838     */
839    static final boolean VALIDATE_UID_STATES = true;
840    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
841
842    /**
843     * Packages that the user has asked to have run in screen size
844     * compatibility mode instead of filling the screen.
845     */
846    final CompatModePackages mCompatModePackages;
847
848    /**
849     * Set of IntentSenderRecord objects that are currently active.
850     */
851    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
852            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
853
854    /**
855     * Fingerprints (hashCode()) of stack traces that we've
856     * already logged DropBox entries for.  Guarded by itself.  If
857     * something (rogue user app) forces this over
858     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
859     */
860    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
861    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
862
863    /**
864     * Strict Mode background batched logging state.
865     *
866     * The string buffer is guarded by itself, and its lock is also
867     * used to determine if another batched write is already
868     * in-flight.
869     */
870    private final StringBuilder mStrictModeBuffer = new StringBuilder();
871
872    /**
873     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
874     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
875     */
876    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
877
878    /**
879     * Resolver for broadcast intents to registered receivers.
880     * Holds BroadcastFilter (subclass of IntentFilter).
881     */
882    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
883            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
884        @Override
885        protected boolean allowFilterResult(
886                BroadcastFilter filter, List<BroadcastFilter> dest) {
887            IBinder target = filter.receiverList.receiver.asBinder();
888            for (int i = dest.size() - 1; i >= 0; i--) {
889                if (dest.get(i).receiverList.receiver.asBinder() == target) {
890                    return false;
891                }
892            }
893            return true;
894        }
895
896        @Override
897        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
898            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
899                    || userId == filter.owningUserId) {
900                return super.newResult(filter, match, userId);
901            }
902            return null;
903        }
904
905        @Override
906        protected BroadcastFilter[] newArray(int size) {
907            return new BroadcastFilter[size];
908        }
909
910        @Override
911        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
912            return packageName.equals(filter.packageName);
913        }
914    };
915
916    /**
917     * State of all active sticky broadcasts per user.  Keys are the action of the
918     * sticky Intent, values are an ArrayList of all broadcasted intents with
919     * that action (which should usually be one).  The SparseArray is keyed
920     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
921     * for stickies that are sent to all users.
922     */
923    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
924            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
925
926    final ActiveServices mServices;
927
928    final static class Association {
929        final int mSourceUid;
930        final String mSourceProcess;
931        final int mTargetUid;
932        final ComponentName mTargetComponent;
933        final String mTargetProcess;
934
935        int mCount;
936        long mTime;
937
938        int mNesting;
939        long mStartTime;
940
941        // states of the source process when the bind occurred.
942        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
943        long mLastStateUptime;
944        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
945                - ActivityManager.MIN_PROCESS_STATE+1];
946
947        Association(int sourceUid, String sourceProcess, int targetUid,
948                ComponentName targetComponent, String targetProcess) {
949            mSourceUid = sourceUid;
950            mSourceProcess = sourceProcess;
951            mTargetUid = targetUid;
952            mTargetComponent = targetComponent;
953            mTargetProcess = targetProcess;
954        }
955    }
956
957    /**
958     * When service association tracking is enabled, this is all of the associations we
959     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
960     * -> association data.
961     */
962    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
963            mAssociations = new SparseArray<>();
964    boolean mTrackingAssociations;
965
966    /**
967     * Backup/restore process management
968     */
969    String mBackupAppName = null;
970    BackupRecord mBackupTarget = null;
971
972    final ProviderMap mProviderMap;
973
974    /**
975     * List of content providers who have clients waiting for them.  The
976     * application is currently being launched and the provider will be
977     * removed from this list once it is published.
978     */
979    final ArrayList<ContentProviderRecord> mLaunchingProviders
980            = new ArrayList<ContentProviderRecord>();
981
982    /**
983     * File storing persisted {@link #mGrantedUriPermissions}.
984     */
985    private final AtomicFile mGrantFile;
986
987    /** XML constants used in {@link #mGrantFile} */
988    private static final String TAG_URI_GRANTS = "uri-grants";
989    private static final String TAG_URI_GRANT = "uri-grant";
990    private static final String ATTR_USER_HANDLE = "userHandle";
991    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
992    private static final String ATTR_TARGET_USER_ID = "targetUserId";
993    private static final String ATTR_SOURCE_PKG = "sourcePkg";
994    private static final String ATTR_TARGET_PKG = "targetPkg";
995    private static final String ATTR_URI = "uri";
996    private static final String ATTR_MODE_FLAGS = "modeFlags";
997    private static final String ATTR_CREATED_TIME = "createdTime";
998    private static final String ATTR_PREFIX = "prefix";
999
1000    /**
1001     * Global set of specific {@link Uri} permissions that have been granted.
1002     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1003     * to {@link UriPermission#uri} to {@link UriPermission}.
1004     */
1005    @GuardedBy("this")
1006    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1007            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1008
1009    public static class GrantUri {
1010        public final int sourceUserId;
1011        public final Uri uri;
1012        public boolean prefix;
1013
1014        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1015            this.sourceUserId = sourceUserId;
1016            this.uri = uri;
1017            this.prefix = prefix;
1018        }
1019
1020        @Override
1021        public int hashCode() {
1022            int hashCode = 1;
1023            hashCode = 31 * hashCode + sourceUserId;
1024            hashCode = 31 * hashCode + uri.hashCode();
1025            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1026            return hashCode;
1027        }
1028
1029        @Override
1030        public boolean equals(Object o) {
1031            if (o instanceof GrantUri) {
1032                GrantUri other = (GrantUri) o;
1033                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1034                        && prefix == other.prefix;
1035            }
1036            return false;
1037        }
1038
1039        @Override
1040        public String toString() {
1041            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1042            if (prefix) result += " [prefix]";
1043            return result;
1044        }
1045
1046        public String toSafeString() {
1047            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1048            if (prefix) result += " [prefix]";
1049            return result;
1050        }
1051
1052        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1053            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1054                    ContentProvider.getUriWithoutUserId(uri), false);
1055        }
1056    }
1057
1058    CoreSettingsObserver mCoreSettingsObserver;
1059
1060    FontScaleSettingObserver mFontScaleSettingObserver;
1061
1062    private final class FontScaleSettingObserver extends ContentObserver {
1063        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1064
1065        public FontScaleSettingObserver() {
1066            super(mHandler);
1067            ContentResolver resolver = mContext.getContentResolver();
1068            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1069        }
1070
1071        @Override
1072        public void onChange(boolean selfChange, Uri uri) {
1073            if (mFontScaleUri.equals(uri)) {
1074                updateFontScaleIfNeeded();
1075            }
1076        }
1077    }
1078
1079    /**
1080     * Thread-local storage used to carry caller permissions over through
1081     * indirect content-provider access.
1082     */
1083    private class Identity {
1084        public final IBinder token;
1085        public final int pid;
1086        public final int uid;
1087
1088        Identity(IBinder _token, int _pid, int _uid) {
1089            token = _token;
1090            pid = _pid;
1091            uid = _uid;
1092        }
1093    }
1094
1095    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1096
1097    /**
1098     * All information we have collected about the runtime performance of
1099     * any user id that can impact battery performance.
1100     */
1101    final BatteryStatsService mBatteryStatsService;
1102
1103    /**
1104     * Information about component usage
1105     */
1106    UsageStatsManagerInternal mUsageStatsService;
1107
1108    /**
1109     * Access to DeviceIdleController service.
1110     */
1111    DeviceIdleController.LocalService mLocalDeviceIdleController;
1112
1113    /**
1114     * Information about and control over application operations
1115     */
1116    final AppOpsService mAppOpsService;
1117
1118    /**
1119     * Current configuration information.  HistoryRecord objects are given
1120     * a reference to this object to indicate which configuration they are
1121     * currently running in, so this object must be kept immutable.
1122     */
1123    Configuration mConfiguration = new Configuration();
1124
1125    /**
1126     * Current sequencing integer of the configuration, for skipping old
1127     * configurations.
1128     */
1129    int mConfigurationSeq = 0;
1130
1131    boolean mSuppressResizeConfigChanges = false;
1132
1133    /**
1134     * Hardware-reported OpenGLES version.
1135     */
1136    final int GL_ES_VERSION;
1137
1138    /**
1139     * List of initialization arguments to pass to all processes when binding applications to them.
1140     * For example, references to the commonly used services.
1141     */
1142    HashMap<String, IBinder> mAppBindArgs;
1143
1144    /**
1145     * Temporary to avoid allocations.  Protected by main lock.
1146     */
1147    final StringBuilder mStringBuilder = new StringBuilder(256);
1148
1149    /**
1150     * Used to control how we initialize the service.
1151     */
1152    ComponentName mTopComponent;
1153    String mTopAction = Intent.ACTION_MAIN;
1154    String mTopData;
1155
1156    volatile boolean mProcessesReady = false;
1157    volatile boolean mSystemReady = false;
1158    volatile boolean mOnBattery = false;
1159    volatile int mFactoryTest;
1160
1161    @GuardedBy("this") boolean mBooting = false;
1162    @GuardedBy("this") boolean mCallFinishBooting = false;
1163    @GuardedBy("this") boolean mBootAnimationComplete = false;
1164    @GuardedBy("this") boolean mLaunchWarningShown = false;
1165    @GuardedBy("this") boolean mCheckedForSetup = false;
1166
1167    Context mContext;
1168
1169    /**
1170     * The time at which we will allow normal application switches again,
1171     * after a call to {@link #stopAppSwitches()}.
1172     */
1173    long mAppSwitchesAllowedTime;
1174
1175    /**
1176     * This is set to true after the first switch after mAppSwitchesAllowedTime
1177     * is set; any switches after that will clear the time.
1178     */
1179    boolean mDidAppSwitch;
1180
1181    /**
1182     * Last time (in realtime) at which we checked for power usage.
1183     */
1184    long mLastPowerCheckRealtime;
1185
1186    /**
1187     * Last time (in uptime) at which we checked for power usage.
1188     */
1189    long mLastPowerCheckUptime;
1190
1191    /**
1192     * Set while we are wanting to sleep, to prevent any
1193     * activities from being started/resumed.
1194     */
1195    private boolean mSleeping = false;
1196
1197    /**
1198     * The process state used for processes that are running the top activities.
1199     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1200     */
1201    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1202
1203    /**
1204     * Set while we are running a voice interaction.  This overrides
1205     * sleeping while it is active.
1206     */
1207    private IVoiceInteractionSession mRunningVoice;
1208
1209    /**
1210     * For some direct access we need to power manager.
1211     */
1212    PowerManagerInternal mLocalPowerManager;
1213
1214    /**
1215     * We want to hold a wake lock while running a voice interaction session, since
1216     * this may happen with the screen off and we need to keep the CPU running to
1217     * be able to continue to interact with the user.
1218     */
1219    PowerManager.WakeLock mVoiceWakeLock;
1220
1221    /**
1222     * State of external calls telling us if the device is awake or asleep.
1223     */
1224    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1225
1226    /**
1227     * A list of tokens that cause the top activity to be put to sleep.
1228     * They are used by components that may hide and block interaction with underlying
1229     * activities.
1230     */
1231    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1232
1233    static final int LOCK_SCREEN_HIDDEN = 0;
1234    static final int LOCK_SCREEN_LEAVING = 1;
1235    static final int LOCK_SCREEN_SHOWN = 2;
1236    /**
1237     * State of external call telling us if the lock screen is shown.
1238     */
1239    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1240
1241    /**
1242     * Set if we are shutting down the system, similar to sleeping.
1243     */
1244    boolean mShuttingDown = false;
1245
1246    /**
1247     * Current sequence id for oom_adj computation traversal.
1248     */
1249    int mAdjSeq = 0;
1250
1251    /**
1252     * Current sequence id for process LRU updating.
1253     */
1254    int mLruSeq = 0;
1255
1256    /**
1257     * Keep track of the non-cached/empty process we last found, to help
1258     * determine how to distribute cached/empty processes next time.
1259     */
1260    int mNumNonCachedProcs = 0;
1261
1262    /**
1263     * Keep track of the number of cached hidden procs, to balance oom adj
1264     * distribution between those and empty procs.
1265     */
1266    int mNumCachedHiddenProcs = 0;
1267
1268    /**
1269     * Keep track of the number of service processes we last found, to
1270     * determine on the next iteration which should be B services.
1271     */
1272    int mNumServiceProcs = 0;
1273    int mNewNumAServiceProcs = 0;
1274    int mNewNumServiceProcs = 0;
1275
1276    /**
1277     * Allow the current computed overall memory level of the system to go down?
1278     * This is set to false when we are killing processes for reasons other than
1279     * memory management, so that the now smaller process list will not be taken as
1280     * an indication that memory is tighter.
1281     */
1282    boolean mAllowLowerMemLevel = false;
1283
1284    /**
1285     * The last computed memory level, for holding when we are in a state that
1286     * processes are going away for other reasons.
1287     */
1288    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1289
1290    /**
1291     * The last total number of process we have, to determine if changes actually look
1292     * like a shrinking number of process due to lower RAM.
1293     */
1294    int mLastNumProcesses;
1295
1296    /**
1297     * The uptime of the last time we performed idle maintenance.
1298     */
1299    long mLastIdleTime = SystemClock.uptimeMillis();
1300
1301    /**
1302     * Total time spent with RAM that has been added in the past since the last idle time.
1303     */
1304    long mLowRamTimeSinceLastIdle = 0;
1305
1306    /**
1307     * If RAM is currently low, when that horrible situation started.
1308     */
1309    long mLowRamStartTime = 0;
1310
1311    /**
1312     * For reporting to battery stats the current top application.
1313     */
1314    private String mCurResumedPackage = null;
1315    private int mCurResumedUid = -1;
1316
1317    /**
1318     * For reporting to battery stats the apps currently running foreground
1319     * service.  The ProcessMap is package/uid tuples; each of these contain
1320     * an array of the currently foreground processes.
1321     */
1322    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1323            = new ProcessMap<ArrayList<ProcessRecord>>();
1324
1325    /**
1326     * This is set if we had to do a delayed dexopt of an app before launching
1327     * it, to increase the ANR timeouts in that case.
1328     */
1329    boolean mDidDexOpt;
1330
1331    /**
1332     * Set if the systemServer made a call to enterSafeMode.
1333     */
1334    boolean mSafeMode;
1335
1336    /**
1337     * If true, we are running under a test environment so will sample PSS from processes
1338     * much more rapidly to try to collect better data when the tests are rapidly
1339     * running through apps.
1340     */
1341    boolean mTestPssMode = false;
1342
1343    String mDebugApp = null;
1344    boolean mWaitForDebugger = false;
1345    boolean mDebugTransient = false;
1346    String mOrigDebugApp = null;
1347    boolean mOrigWaitForDebugger = false;
1348    boolean mAlwaysFinishActivities = false;
1349    boolean mLenientBackgroundCheck = false;
1350    boolean mForceResizableActivities;
1351    boolean mSupportsMultiWindow;
1352    boolean mSupportsFreeformWindowManagement;
1353    boolean mSupportsPictureInPicture;
1354    boolean mSupportsLeanbackOnly;
1355    Rect mDefaultPinnedStackBounds;
1356    IActivityController mController = null;
1357    boolean mControllerIsAMonkey = false;
1358    String mProfileApp = null;
1359    ProcessRecord mProfileProc = null;
1360    String mProfileFile;
1361    ParcelFileDescriptor mProfileFd;
1362    int mSamplingInterval = 0;
1363    boolean mAutoStopProfiler = false;
1364    int mProfileType = 0;
1365    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1366    String mMemWatchDumpProcName;
1367    String mMemWatchDumpFile;
1368    int mMemWatchDumpPid;
1369    int mMemWatchDumpUid;
1370    String mTrackAllocationApp = null;
1371    String mNativeDebuggingApp = null;
1372
1373    final long[] mTmpLong = new long[2];
1374
1375    static final class ProcessChangeItem {
1376        static final int CHANGE_ACTIVITIES = 1<<0;
1377        static final int CHANGE_PROCESS_STATE = 1<<1;
1378        int changes;
1379        int uid;
1380        int pid;
1381        int processState;
1382        boolean foregroundActivities;
1383    }
1384
1385    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1386    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1387
1388    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1389    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1390
1391    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1392    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1393
1394    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1395    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1396
1397    /**
1398     * Runtime CPU use collection thread.  This object's lock is used to
1399     * perform synchronization with the thread (notifying it to run).
1400     */
1401    final Thread mProcessCpuThread;
1402
1403    /**
1404     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1405     * Must acquire this object's lock when accessing it.
1406     * NOTE: this lock will be held while doing long operations (trawling
1407     * through all processes in /proc), so it should never be acquired by
1408     * any critical paths such as when holding the main activity manager lock.
1409     */
1410    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1411            MONITOR_THREAD_CPU_USAGE);
1412    final AtomicLong mLastCpuTime = new AtomicLong(0);
1413    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1414
1415    long mLastWriteTime = 0;
1416
1417    /**
1418     * Used to retain an update lock when the foreground activity is in
1419     * immersive mode.
1420     */
1421    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1422
1423    /**
1424     * Set to true after the system has finished booting.
1425     */
1426    boolean mBooted = false;
1427
1428    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1429    int mProcessLimitOverride = -1;
1430
1431    WindowManagerService mWindowManager;
1432    final ActivityThread mSystemThread;
1433
1434    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1435        final ProcessRecord mApp;
1436        final int mPid;
1437        final IApplicationThread mAppThread;
1438
1439        AppDeathRecipient(ProcessRecord app, int pid,
1440                IApplicationThread thread) {
1441            if (DEBUG_ALL) Slog.v(
1442                TAG, "New death recipient " + this
1443                + " for thread " + thread.asBinder());
1444            mApp = app;
1445            mPid = pid;
1446            mAppThread = thread;
1447        }
1448
1449        @Override
1450        public void binderDied() {
1451            if (DEBUG_ALL) Slog.v(
1452                TAG, "Death received in " + this
1453                + " for thread " + mAppThread.asBinder());
1454            synchronized(ActivityManagerService.this) {
1455                appDiedLocked(mApp, mPid, mAppThread, true);
1456            }
1457        }
1458    }
1459
1460    static final int SHOW_ERROR_UI_MSG = 1;
1461    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1462    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1463    static final int UPDATE_CONFIGURATION_MSG = 4;
1464    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1465    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1466    static final int SERVICE_TIMEOUT_MSG = 12;
1467    static final int UPDATE_TIME_ZONE = 13;
1468    static final int SHOW_UID_ERROR_UI_MSG = 14;
1469    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1470    static final int PROC_START_TIMEOUT_MSG = 20;
1471    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1472    static final int KILL_APPLICATION_MSG = 22;
1473    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1474    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1475    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1476    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1477    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1478    static final int CLEAR_DNS_CACHE_MSG = 28;
1479    static final int UPDATE_HTTP_PROXY_MSG = 29;
1480    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1481    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1482    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1483    static final int REPORT_MEM_USAGE_MSG = 33;
1484    static final int REPORT_USER_SWITCH_MSG = 34;
1485    static final int CONTINUE_USER_SWITCH_MSG = 35;
1486    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1487    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1488    static final int PERSIST_URI_GRANTS_MSG = 38;
1489    static final int REQUEST_ALL_PSS_MSG = 39;
1490    static final int START_PROFILES_MSG = 40;
1491    static final int UPDATE_TIME = 41;
1492    static final int SYSTEM_USER_START_MSG = 42;
1493    static final int SYSTEM_USER_CURRENT_MSG = 43;
1494    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1495    static final int FINISH_BOOTING_MSG = 45;
1496    static final int START_USER_SWITCH_UI_MSG = 46;
1497    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1498    static final int DISMISS_DIALOG_UI_MSG = 48;
1499    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1500    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1501    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1502    static final int DELETE_DUMPHEAP_MSG = 52;
1503    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1504    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1505    static final int REPORT_TIME_TRACKER_MSG = 55;
1506    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1507    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1508    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1509    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1510    static final int IDLE_UIDS_MSG = 60;
1511    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1512    static final int LOG_STACK_STATE = 62;
1513    static final int VR_MODE_CHANGE_MSG = 63;
1514    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1515    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1516    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1517    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1518    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1519    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1520    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1521
1522    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1523    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1524    static final int FIRST_COMPAT_MODE_MSG = 300;
1525    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1526
1527    static ServiceThread sKillThread = null;
1528    static KillHandler sKillHandler = null;
1529
1530    CompatModeDialog mCompatModeDialog;
1531    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1532    long mLastMemUsageReportTime = 0;
1533
1534    /**
1535     * Flag whether the current user is a "monkey", i.e. whether
1536     * the UI is driven by a UI automation tool.
1537     */
1538    private boolean mUserIsMonkey;
1539
1540    /** Flag whether the device has a Recents UI */
1541    boolean mHasRecents;
1542
1543    /** The dimensions of the thumbnails in the Recents UI. */
1544    int mThumbnailWidth;
1545    int mThumbnailHeight;
1546    float mFullscreenThumbnailScale;
1547
1548    final ServiceThread mHandlerThread;
1549    final MainHandler mHandler;
1550    final UiHandler mUiHandler;
1551
1552    PackageManagerInternal mPackageManagerInt;
1553
1554    // VoiceInteraction session ID that changes for each new request except when
1555    // being called for multiwindow assist in a single session.
1556    private int mViSessionId = 1000;
1557
1558    final class KillHandler extends Handler {
1559        static final int KILL_PROCESS_GROUP_MSG = 4000;
1560
1561        public KillHandler(Looper looper) {
1562            super(looper, null, true);
1563        }
1564
1565        @Override
1566        public void handleMessage(Message msg) {
1567            switch (msg.what) {
1568                case KILL_PROCESS_GROUP_MSG:
1569                {
1570                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1571                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1572                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1573                }
1574                break;
1575
1576                default:
1577                    super.handleMessage(msg);
1578            }
1579        }
1580    }
1581
1582    final class UiHandler extends Handler {
1583        public UiHandler() {
1584            super(com.android.server.UiThread.get().getLooper(), null, true);
1585        }
1586
1587        @Override
1588        public void handleMessage(Message msg) {
1589            switch (msg.what) {
1590            case SHOW_ERROR_UI_MSG: {
1591                mAppErrors.handleShowAppErrorUi(msg);
1592                ensureBootCompleted();
1593            } break;
1594            case SHOW_NOT_RESPONDING_UI_MSG: {
1595                mAppErrors.handleShowAnrUi(msg);
1596                ensureBootCompleted();
1597            } break;
1598            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1599                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1600                synchronized (ActivityManagerService.this) {
1601                    ProcessRecord proc = (ProcessRecord) data.get("app");
1602                    if (proc == null) {
1603                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1604                        break;
1605                    }
1606                    if (proc.crashDialog != null) {
1607                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1608                        return;
1609                    }
1610                    AppErrorResult res = (AppErrorResult) data.get("result");
1611                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1612                        Dialog d = new StrictModeViolationDialog(mContext,
1613                                ActivityManagerService.this, res, proc);
1614                        d.show();
1615                        proc.crashDialog = d;
1616                    } else {
1617                        // The device is asleep, so just pretend that the user
1618                        // saw a crash dialog and hit "force quit".
1619                        res.set(0);
1620                    }
1621                }
1622                ensureBootCompleted();
1623            } break;
1624            case SHOW_FACTORY_ERROR_UI_MSG: {
1625                Dialog d = new FactoryErrorDialog(
1626                    mContext, msg.getData().getCharSequence("msg"));
1627                d.show();
1628                ensureBootCompleted();
1629            } break;
1630            case WAIT_FOR_DEBUGGER_UI_MSG: {
1631                synchronized (ActivityManagerService.this) {
1632                    ProcessRecord app = (ProcessRecord)msg.obj;
1633                    if (msg.arg1 != 0) {
1634                        if (!app.waitedForDebugger) {
1635                            Dialog d = new AppWaitingForDebuggerDialog(
1636                                    ActivityManagerService.this,
1637                                    mContext, app);
1638                            app.waitDialog = d;
1639                            app.waitedForDebugger = true;
1640                            d.show();
1641                        }
1642                    } else {
1643                        if (app.waitDialog != null) {
1644                            app.waitDialog.dismiss();
1645                            app.waitDialog = null;
1646                        }
1647                    }
1648                }
1649            } break;
1650            case SHOW_UID_ERROR_UI_MSG: {
1651                if (mShowDialogs) {
1652                    AlertDialog d = new BaseErrorDialog(mContext);
1653                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1654                    d.setCancelable(false);
1655                    d.setTitle(mContext.getText(R.string.android_system_label));
1656                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1657                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1658                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1659                    d.show();
1660                }
1661            } break;
1662            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1663                if (mShowDialogs) {
1664                    AlertDialog d = new BaseErrorDialog(mContext);
1665                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1666                    d.setCancelable(false);
1667                    d.setTitle(mContext.getText(R.string.android_system_label));
1668                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1669                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1670                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1671                    d.show();
1672                }
1673            } break;
1674            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1675                synchronized (ActivityManagerService.this) {
1676                    ActivityRecord ar = (ActivityRecord) msg.obj;
1677                    if (mCompatModeDialog != null) {
1678                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1679                                ar.info.applicationInfo.packageName)) {
1680                            return;
1681                        }
1682                        mCompatModeDialog.dismiss();
1683                        mCompatModeDialog = null;
1684                    }
1685                    if (ar != null && false) {
1686                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1687                                ar.packageName)) {
1688                            int mode = mCompatModePackages.computeCompatModeLocked(
1689                                    ar.info.applicationInfo);
1690                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1691                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1692                                mCompatModeDialog = new CompatModeDialog(
1693                                        ActivityManagerService.this, mContext,
1694                                        ar.info.applicationInfo);
1695                                mCompatModeDialog.show();
1696                            }
1697                        }
1698                    }
1699                }
1700                break;
1701            }
1702            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1703                synchronized (ActivityManagerService.this) {
1704                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1705                    if (mUnsupportedDisplaySizeDialog != null) {
1706                        mUnsupportedDisplaySizeDialog.dismiss();
1707                        mUnsupportedDisplaySizeDialog = null;
1708                    }
1709                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1710                            ar.packageName)) {
1711                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1712                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1713                        mUnsupportedDisplaySizeDialog.show();
1714                    }
1715                }
1716                break;
1717            }
1718            case START_USER_SWITCH_UI_MSG: {
1719                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1720                break;
1721            }
1722            case DISMISS_DIALOG_UI_MSG: {
1723                final Dialog d = (Dialog) msg.obj;
1724                d.dismiss();
1725                break;
1726            }
1727            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1728                dispatchProcessesChanged();
1729                break;
1730            }
1731            case DISPATCH_PROCESS_DIED_UI_MSG: {
1732                final int pid = msg.arg1;
1733                final int uid = msg.arg2;
1734                dispatchProcessDied(pid, uid);
1735                break;
1736            }
1737            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1738                dispatchUidsChanged();
1739            } break;
1740            }
1741        }
1742    }
1743
1744    final class MainHandler extends Handler {
1745        public MainHandler(Looper looper) {
1746            super(looper, null, true);
1747        }
1748
1749        @Override
1750        public void handleMessage(Message msg) {
1751            switch (msg.what) {
1752            case UPDATE_CONFIGURATION_MSG: {
1753                final ContentResolver resolver = mContext.getContentResolver();
1754                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1755                        msg.arg1);
1756            } break;
1757            case GC_BACKGROUND_PROCESSES_MSG: {
1758                synchronized (ActivityManagerService.this) {
1759                    performAppGcsIfAppropriateLocked();
1760                }
1761            } break;
1762            case SERVICE_TIMEOUT_MSG: {
1763                if (mDidDexOpt) {
1764                    mDidDexOpt = false;
1765                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1766                    nmsg.obj = msg.obj;
1767                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1768                    return;
1769                }
1770                mServices.serviceTimeout((ProcessRecord)msg.obj);
1771            } break;
1772            case UPDATE_TIME_ZONE: {
1773                synchronized (ActivityManagerService.this) {
1774                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1775                        ProcessRecord r = mLruProcesses.get(i);
1776                        if (r.thread != null) {
1777                            try {
1778                                r.thread.updateTimeZone();
1779                            } catch (RemoteException ex) {
1780                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1781                            }
1782                        }
1783                    }
1784                }
1785            } break;
1786            case CLEAR_DNS_CACHE_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.clearDnsCache();
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799            } break;
1800            case UPDATE_HTTP_PROXY_MSG: {
1801                ProxyInfo proxy = (ProxyInfo)msg.obj;
1802                String host = "";
1803                String port = "";
1804                String exclList = "";
1805                Uri pacFileUrl = Uri.EMPTY;
1806                if (proxy != null) {
1807                    host = proxy.getHost();
1808                    port = Integer.toString(proxy.getPort());
1809                    exclList = proxy.getExclusionListAsString();
1810                    pacFileUrl = proxy.getPacFileUrl();
1811                }
1812                synchronized (ActivityManagerService.this) {
1813                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1814                        ProcessRecord r = mLruProcesses.get(i);
1815                        if (r.thread != null) {
1816                            try {
1817                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1818                            } catch (RemoteException ex) {
1819                                Slog.w(TAG, "Failed to update http proxy for: " +
1820                                        r.info.processName);
1821                            }
1822                        }
1823                    }
1824                }
1825            } break;
1826            case PROC_START_TIMEOUT_MSG: {
1827                if (mDidDexOpt) {
1828                    mDidDexOpt = false;
1829                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1830                    nmsg.obj = msg.obj;
1831                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1832                    return;
1833                }
1834                ProcessRecord app = (ProcessRecord)msg.obj;
1835                synchronized (ActivityManagerService.this) {
1836                    processStartTimedOutLocked(app);
1837                }
1838            } break;
1839            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1840                ProcessRecord app = (ProcessRecord)msg.obj;
1841                synchronized (ActivityManagerService.this) {
1842                    processContentProviderPublishTimedOutLocked(app);
1843                }
1844            } break;
1845            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1846                synchronized (ActivityManagerService.this) {
1847                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1848                }
1849            } break;
1850            case KILL_APPLICATION_MSG: {
1851                synchronized (ActivityManagerService.this) {
1852                    int appid = msg.arg1;
1853                    boolean restart = (msg.arg2 == 1);
1854                    Bundle bundle = (Bundle)msg.obj;
1855                    String pkg = bundle.getString("pkg");
1856                    String reason = bundle.getString("reason");
1857                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1858                            false, UserHandle.USER_ALL, reason);
1859                }
1860            } break;
1861            case FINALIZE_PENDING_INTENT_MSG: {
1862                ((PendingIntentRecord)msg.obj).completeFinalize();
1863            } break;
1864            case POST_HEAVY_NOTIFICATION_MSG: {
1865                INotificationManager inm = NotificationManager.getService();
1866                if (inm == null) {
1867                    return;
1868                }
1869
1870                ActivityRecord root = (ActivityRecord)msg.obj;
1871                ProcessRecord process = root.app;
1872                if (process == null) {
1873                    return;
1874                }
1875
1876                try {
1877                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1878                    String text = mContext.getString(R.string.heavy_weight_notification,
1879                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1880                    Notification notification = new Notification.Builder(context)
1881                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1882                            .setWhen(0)
1883                            .setOngoing(true)
1884                            .setTicker(text)
1885                            .setColor(mContext.getColor(
1886                                    com.android.internal.R.color.system_notification_accent_color))
1887                            .setContentTitle(text)
1888                            .setContentText(
1889                                    mContext.getText(R.string.heavy_weight_notification_detail))
1890                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1891                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1892                                    new UserHandle(root.userId)))
1893                            .build();
1894                    try {
1895                        int[] outId = new int[1];
1896                        inm.enqueueNotificationWithTag("android", "android", null,
1897                                R.string.heavy_weight_notification,
1898                                notification, outId, root.userId);
1899                    } catch (RuntimeException e) {
1900                        Slog.w(ActivityManagerService.TAG,
1901                                "Error showing notification for heavy-weight app", e);
1902                    } catch (RemoteException e) {
1903                    }
1904                } catch (NameNotFoundException e) {
1905                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1906                }
1907            } break;
1908            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1909                INotificationManager inm = NotificationManager.getService();
1910                if (inm == null) {
1911                    return;
1912                }
1913                try {
1914                    inm.cancelNotificationWithTag("android", null,
1915                            R.string.heavy_weight_notification,  msg.arg1);
1916                } catch (RuntimeException e) {
1917                    Slog.w(ActivityManagerService.TAG,
1918                            "Error canceling notification for service", e);
1919                } catch (RemoteException e) {
1920                }
1921            } break;
1922            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1923                synchronized (ActivityManagerService.this) {
1924                    checkExcessivePowerUsageLocked(true);
1925                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1926                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1927                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1928                }
1929            } break;
1930            case REPORT_MEM_USAGE_MSG: {
1931                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1932                Thread thread = new Thread() {
1933                    @Override public void run() {
1934                        reportMemUsage(memInfos);
1935                    }
1936                };
1937                thread.start();
1938                break;
1939            }
1940            case REPORT_USER_SWITCH_MSG: {
1941                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1942                break;
1943            }
1944            case CONTINUE_USER_SWITCH_MSG: {
1945                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1946                break;
1947            }
1948            case USER_SWITCH_TIMEOUT_MSG: {
1949                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1950                break;
1951            }
1952            case IMMERSIVE_MODE_LOCK_MSG: {
1953                final boolean nextState = (msg.arg1 != 0);
1954                if (mUpdateLock.isHeld() != nextState) {
1955                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1956                            "Applying new update lock state '" + nextState
1957                            + "' for " + (ActivityRecord)msg.obj);
1958                    if (nextState) {
1959                        mUpdateLock.acquire();
1960                    } else {
1961                        mUpdateLock.release();
1962                    }
1963                }
1964                break;
1965            }
1966            case PERSIST_URI_GRANTS_MSG: {
1967                writeGrantedUriPermissions();
1968                break;
1969            }
1970            case REQUEST_ALL_PSS_MSG: {
1971                synchronized (ActivityManagerService.this) {
1972                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1973                }
1974                break;
1975            }
1976            case START_PROFILES_MSG: {
1977                synchronized (ActivityManagerService.this) {
1978                    mUserController.startProfilesLocked();
1979                }
1980                break;
1981            }
1982            case UPDATE_TIME: {
1983                synchronized (ActivityManagerService.this) {
1984                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985                        ProcessRecord r = mLruProcesses.get(i);
1986                        if (r.thread != null) {
1987                            try {
1988                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1989                            } catch (RemoteException ex) {
1990                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1991                            }
1992                        }
1993                    }
1994                }
1995                break;
1996            }
1997            case SYSTEM_USER_START_MSG: {
1998                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1999                        Integer.toString(msg.arg1), msg.arg1);
2000                mSystemServiceManager.startUser(msg.arg1);
2001                break;
2002            }
2003            case SYSTEM_USER_UNLOCK_MSG: {
2004                final int userId = msg.arg1;
2005                mSystemServiceManager.unlockUser(userId);
2006                synchronized (ActivityManagerService.this) {
2007                    mRecentTasks.loadUserRecentsLocked(userId);
2008                }
2009                if (userId == UserHandle.USER_SYSTEM) {
2010                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2011                }
2012                installEncryptionUnawareProviders(userId);
2013                mUserController.finishUserUnlocked((UserState) msg.obj);
2014                break;
2015            }
2016            case SYSTEM_USER_CURRENT_MSG: {
2017                mBatteryStatsService.noteEvent(
2018                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2019                        Integer.toString(msg.arg2), msg.arg2);
2020                mBatteryStatsService.noteEvent(
2021                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2022                        Integer.toString(msg.arg1), msg.arg1);
2023                mSystemServiceManager.switchUser(msg.arg1);
2024                break;
2025            }
2026            case ENTER_ANIMATION_COMPLETE_MSG: {
2027                synchronized (ActivityManagerService.this) {
2028                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2029                    if (r != null && r.app != null && r.app.thread != null) {
2030                        try {
2031                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2032                        } catch (RemoteException e) {
2033                        }
2034                    }
2035                }
2036                break;
2037            }
2038            case FINISH_BOOTING_MSG: {
2039                if (msg.arg1 != 0) {
2040                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2041                    finishBooting();
2042                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2043                }
2044                if (msg.arg2 != 0) {
2045                    enableScreenAfterBoot();
2046                }
2047                break;
2048            }
2049            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2050                try {
2051                    Locale l = (Locale) msg.obj;
2052                    IBinder service = ServiceManager.getService("mount");
2053                    IMountService mountService = IMountService.Stub.asInterface(service);
2054                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2055                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2056                } catch (RemoteException e) {
2057                    Log.e(TAG, "Error storing locale for decryption UI", e);
2058                }
2059                break;
2060            }
2061            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2062                synchronized (ActivityManagerService.this) {
2063                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2064                        try {
2065                            // Make a one-way callback to the listener
2066                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2067                        } catch (RemoteException e){
2068                            // Handled by the RemoteCallbackList
2069                        }
2070                    }
2071                    mTaskStackListeners.finishBroadcast();
2072                }
2073                break;
2074            }
2075            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2076                synchronized (ActivityManagerService.this) {
2077                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2078                        try {
2079                            // Make a one-way callback to the listener
2080                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2081                        } catch (RemoteException e){
2082                            // Handled by the RemoteCallbackList
2083                        }
2084                    }
2085                    mTaskStackListeners.finishBroadcast();
2086                }
2087                break;
2088            }
2089            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2090                synchronized (ActivityManagerService.this) {
2091                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2092                        try {
2093                            // Make a one-way callback to the listener
2094                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2095                        } catch (RemoteException e){
2096                            // Handled by the RemoteCallbackList
2097                        }
2098                    }
2099                    mTaskStackListeners.finishBroadcast();
2100                }
2101                break;
2102            }
2103            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2104                synchronized (ActivityManagerService.this) {
2105                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2106                        try {
2107                            // Make a one-way callback to the listener
2108                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2109                        } catch (RemoteException e){
2110                            // Handled by the RemoteCallbackList
2111                        }
2112                    }
2113                    mTaskStackListeners.finishBroadcast();
2114                }
2115                break;
2116            }
2117            case NOTIFY_FORCED_RESIZABLE_MSG: {
2118                synchronized (ActivityManagerService.this) {
2119                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2120                        try {
2121                            // Make a one-way callback to the listener
2122                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2123                                    (String) msg.obj, msg.arg1);
2124                        } catch (RemoteException e){
2125                            // Handled by the RemoteCallbackList
2126                        }
2127                    }
2128                    mTaskStackListeners.finishBroadcast();
2129                }
2130                break;
2131            }
2132                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2133                    synchronized (ActivityManagerService.this) {
2134                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2135                            try {
2136                                // Make a one-way callback to the listener
2137                                mTaskStackListeners.getBroadcastItem(i)
2138                                        .onActivityDismissingDockedStack();
2139                            } catch (RemoteException e){
2140                                // Handled by the RemoteCallbackList
2141                            }
2142                        }
2143                        mTaskStackListeners.finishBroadcast();
2144                    }
2145                    break;
2146                }
2147            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2148                final int uid = msg.arg1;
2149                final byte[] firstPacket = (byte[]) msg.obj;
2150
2151                synchronized (mPidsSelfLocked) {
2152                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2153                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2154                        if (p.uid == uid) {
2155                            try {
2156                                p.thread.notifyCleartextNetwork(firstPacket);
2157                            } catch (RemoteException ignored) {
2158                            }
2159                        }
2160                    }
2161                }
2162                break;
2163            }
2164            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2165                final String procName;
2166                final int uid;
2167                final long memLimit;
2168                final String reportPackage;
2169                synchronized (ActivityManagerService.this) {
2170                    procName = mMemWatchDumpProcName;
2171                    uid = mMemWatchDumpUid;
2172                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2173                    if (val == null) {
2174                        val = mMemWatchProcesses.get(procName, 0);
2175                    }
2176                    if (val != null) {
2177                        memLimit = val.first;
2178                        reportPackage = val.second;
2179                    } else {
2180                        memLimit = 0;
2181                        reportPackage = null;
2182                    }
2183                }
2184                if (procName == null) {
2185                    return;
2186                }
2187
2188                if (DEBUG_PSS) Slog.d(TAG_PSS,
2189                        "Showing dump heap notification from " + procName + "/" + uid);
2190
2191                INotificationManager inm = NotificationManager.getService();
2192                if (inm == null) {
2193                    return;
2194                }
2195
2196                String text = mContext.getString(R.string.dump_heap_notification, procName);
2197
2198
2199                Intent deleteIntent = new Intent();
2200                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2201                Intent intent = new Intent();
2202                intent.setClassName("android", DumpHeapActivity.class.getName());
2203                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2204                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2205                if (reportPackage != null) {
2206                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2207                }
2208                int userId = UserHandle.getUserId(uid);
2209                Notification notification = new Notification.Builder(mContext)
2210                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2211                        .setWhen(0)
2212                        .setOngoing(true)
2213                        .setAutoCancel(true)
2214                        .setTicker(text)
2215                        .setColor(mContext.getColor(
2216                                com.android.internal.R.color.system_notification_accent_color))
2217                        .setContentTitle(text)
2218                        .setContentText(
2219                                mContext.getText(R.string.dump_heap_notification_detail))
2220                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2221                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2222                                new UserHandle(userId)))
2223                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2224                                deleteIntent, 0, UserHandle.SYSTEM))
2225                        .build();
2226
2227                try {
2228                    int[] outId = new int[1];
2229                    inm.enqueueNotificationWithTag("android", "android", null,
2230                            R.string.dump_heap_notification,
2231                            notification, outId, userId);
2232                } catch (RuntimeException e) {
2233                    Slog.w(ActivityManagerService.TAG,
2234                            "Error showing notification for dump heap", e);
2235                } catch (RemoteException e) {
2236                }
2237            } break;
2238            case DELETE_DUMPHEAP_MSG: {
2239                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2240                        DumpHeapActivity.JAVA_URI,
2241                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2242                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2243                        UserHandle.myUserId());
2244                synchronized (ActivityManagerService.this) {
2245                    mMemWatchDumpFile = null;
2246                    mMemWatchDumpProcName = null;
2247                    mMemWatchDumpPid = -1;
2248                    mMemWatchDumpUid = -1;
2249                }
2250            } break;
2251            case FOREGROUND_PROFILE_CHANGED_MSG: {
2252                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2253            } break;
2254            case REPORT_TIME_TRACKER_MSG: {
2255                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2256                tracker.deliverResult(mContext);
2257            } break;
2258            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2259                mUserController.dispatchUserSwitchComplete(msg.arg1);
2260            } break;
2261            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2262                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2263                try {
2264                    connection.shutdown();
2265                } catch (RemoteException e) {
2266                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2267                }
2268                // Only a UiAutomation can set this flag and now that
2269                // it is finished we make sure it is reset to its default.
2270                mUserIsMonkey = false;
2271            } break;
2272            case APP_BOOST_DEACTIVATE_MSG: {
2273                synchronized(ActivityManagerService.this) {
2274                    if (mIsBoosted) {
2275                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2276                            nativeMigrateFromBoost();
2277                            mIsBoosted = false;
2278                            mBoostStartTime = 0;
2279                        } else {
2280                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2281                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2282                        }
2283                    }
2284                }
2285            } break;
2286            case IDLE_UIDS_MSG: {
2287                idleUids();
2288            } break;
2289            case LOG_STACK_STATE: {
2290                synchronized (ActivityManagerService.this) {
2291                    mStackSupervisor.logStackState();
2292                }
2293            } break;
2294            case VR_MODE_CHANGE_MSG: {
2295                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2296                final ActivityRecord r = (ActivityRecord) msg.obj;
2297                boolean vrMode;
2298                ComponentName requestedPackage;
2299                ComponentName callingPackage;
2300                int userId;
2301                synchronized (ActivityManagerService.this) {
2302                    vrMode = r.requestedVrComponent != null;
2303                    requestedPackage = r.requestedVrComponent;
2304                    userId = r.userId;
2305                    callingPackage = r.info.getComponentName();
2306                    if (mInVrMode != vrMode) {
2307                        mInVrMode = vrMode;
2308                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2309                    }
2310                }
2311                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2312            } break;
2313            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2314                final ActivityRecord r = (ActivityRecord) msg.obj;
2315                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2316                if (needsVrMode) {
2317                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2318                            r.info.getComponentName(), false);
2319                }
2320            } break;
2321            }
2322        }
2323    };
2324
2325    static final int COLLECT_PSS_BG_MSG = 1;
2326
2327    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2328        @Override
2329        public void handleMessage(Message msg) {
2330            switch (msg.what) {
2331            case COLLECT_PSS_BG_MSG: {
2332                long start = SystemClock.uptimeMillis();
2333                MemInfoReader memInfo = null;
2334                synchronized (ActivityManagerService.this) {
2335                    if (mFullPssPending) {
2336                        mFullPssPending = false;
2337                        memInfo = new MemInfoReader();
2338                    }
2339                }
2340                if (memInfo != null) {
2341                    updateCpuStatsNow();
2342                    long nativeTotalPss = 0;
2343                    synchronized (mProcessCpuTracker) {
2344                        final int N = mProcessCpuTracker.countStats();
2345                        for (int j=0; j<N; j++) {
2346                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2347                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2348                                // This is definitely an application process; skip it.
2349                                continue;
2350                            }
2351                            synchronized (mPidsSelfLocked) {
2352                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2353                                    // This is one of our own processes; skip it.
2354                                    continue;
2355                                }
2356                            }
2357                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2358                        }
2359                    }
2360                    memInfo.readMemInfo();
2361                    synchronized (ActivityManagerService.this) {
2362                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2363                                + (SystemClock.uptimeMillis()-start) + "ms");
2364                        final long cachedKb = memInfo.getCachedSizeKb();
2365                        final long freeKb = memInfo.getFreeSizeKb();
2366                        final long zramKb = memInfo.getZramTotalSizeKb();
2367                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2368                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2369                                kernelKb*1024, nativeTotalPss*1024);
2370                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2371                                nativeTotalPss);
2372                    }
2373                }
2374
2375                int num = 0;
2376                long[] tmp = new long[2];
2377                do {
2378                    ProcessRecord proc;
2379                    int procState;
2380                    int pid;
2381                    long lastPssTime;
2382                    synchronized (ActivityManagerService.this) {
2383                        if (mPendingPssProcesses.size() <= 0) {
2384                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2385                                    "Collected PSS of " + num + " processes in "
2386                                    + (SystemClock.uptimeMillis() - start) + "ms");
2387                            mPendingPssProcesses.clear();
2388                            return;
2389                        }
2390                        proc = mPendingPssProcesses.remove(0);
2391                        procState = proc.pssProcState;
2392                        lastPssTime = proc.lastPssTime;
2393                        if (proc.thread != null && procState == proc.setProcState
2394                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2395                                        < SystemClock.uptimeMillis()) {
2396                            pid = proc.pid;
2397                        } else {
2398                            proc = null;
2399                            pid = 0;
2400                        }
2401                    }
2402                    if (proc != null) {
2403                        long pss = Debug.getPss(pid, tmp, null);
2404                        synchronized (ActivityManagerService.this) {
2405                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2406                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2407                                num++;
2408                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2409                                        SystemClock.uptimeMillis());
2410                            }
2411                        }
2412                    }
2413                } while (true);
2414            }
2415            }
2416        }
2417    };
2418
2419    public void setSystemProcess() {
2420        try {
2421            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2422            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2423            ServiceManager.addService("meminfo", new MemBinder(this));
2424            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2425            ServiceManager.addService("dbinfo", new DbBinder(this));
2426            if (MONITOR_CPU_USAGE) {
2427                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2428            }
2429            ServiceManager.addService("permission", new PermissionController(this));
2430            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2431
2432            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2433                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2434            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2435
2436            synchronized (this) {
2437                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2438                app.persistent = true;
2439                app.pid = MY_PID;
2440                app.maxAdj = ProcessList.SYSTEM_ADJ;
2441                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2442                synchronized (mPidsSelfLocked) {
2443                    mPidsSelfLocked.put(app.pid, app);
2444                }
2445                updateLruProcessLocked(app, false, null);
2446                updateOomAdjLocked();
2447            }
2448        } catch (PackageManager.NameNotFoundException e) {
2449            throw new RuntimeException(
2450                    "Unable to find android system package", e);
2451        }
2452    }
2453
2454    public void setWindowManager(WindowManagerService wm) {
2455        mWindowManager = wm;
2456        mStackSupervisor.setWindowManager(wm);
2457        mActivityStarter.setWindowManager(wm);
2458    }
2459
2460    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2461        mUsageStatsService = usageStatsManager;
2462    }
2463
2464    public void startObservingNativeCrashes() {
2465        final NativeCrashListener ncl = new NativeCrashListener(this);
2466        ncl.start();
2467    }
2468
2469    public IAppOpsService getAppOpsService() {
2470        return mAppOpsService;
2471    }
2472
2473    static class MemBinder extends Binder {
2474        ActivityManagerService mActivityManagerService;
2475        MemBinder(ActivityManagerService activityManagerService) {
2476            mActivityManagerService = activityManagerService;
2477        }
2478
2479        @Override
2480        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2481            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2482                    != PackageManager.PERMISSION_GRANTED) {
2483                pw.println("Permission Denial: can't dump meminfo from from pid="
2484                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2485                        + " without permission " + android.Manifest.permission.DUMP);
2486                return;
2487            }
2488
2489            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2490        }
2491    }
2492
2493    static class GraphicsBinder extends Binder {
2494        ActivityManagerService mActivityManagerService;
2495        GraphicsBinder(ActivityManagerService activityManagerService) {
2496            mActivityManagerService = activityManagerService;
2497        }
2498
2499        @Override
2500        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2501            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2502                    != PackageManager.PERMISSION_GRANTED) {
2503                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2504                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2505                        + " without permission " + android.Manifest.permission.DUMP);
2506                return;
2507            }
2508
2509            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2510        }
2511    }
2512
2513    static class DbBinder extends Binder {
2514        ActivityManagerService mActivityManagerService;
2515        DbBinder(ActivityManagerService activityManagerService) {
2516            mActivityManagerService = activityManagerService;
2517        }
2518
2519        @Override
2520        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2521            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2522                    != PackageManager.PERMISSION_GRANTED) {
2523                pw.println("Permission Denial: can't dump dbinfo from from pid="
2524                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2525                        + " without permission " + android.Manifest.permission.DUMP);
2526                return;
2527            }
2528
2529            mActivityManagerService.dumpDbInfo(fd, pw, args);
2530        }
2531    }
2532
2533    static class CpuBinder extends Binder {
2534        ActivityManagerService mActivityManagerService;
2535        CpuBinder(ActivityManagerService activityManagerService) {
2536            mActivityManagerService = activityManagerService;
2537        }
2538
2539        @Override
2540        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2541            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2542                    != PackageManager.PERMISSION_GRANTED) {
2543                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2544                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2545                        + " without permission " + android.Manifest.permission.DUMP);
2546                return;
2547            }
2548
2549            synchronized (mActivityManagerService.mProcessCpuTracker) {
2550                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2551                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2552                        SystemClock.uptimeMillis()));
2553            }
2554        }
2555    }
2556
2557    public static final class Lifecycle extends SystemService {
2558        private final ActivityManagerService mService;
2559
2560        public Lifecycle(Context context) {
2561            super(context);
2562            mService = new ActivityManagerService(context);
2563        }
2564
2565        @Override
2566        public void onStart() {
2567            mService.start();
2568        }
2569
2570        public ActivityManagerService getService() {
2571            return mService;
2572        }
2573    }
2574
2575    // Note: This method is invoked on the main thread but may need to attach various
2576    // handlers to other threads.  So take care to be explicit about the looper.
2577    public ActivityManagerService(Context systemContext) {
2578        mContext = systemContext;
2579        mFactoryTest = FactoryTest.getMode();
2580        mSystemThread = ActivityThread.currentActivityThread();
2581
2582        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2583
2584        mHandlerThread = new ServiceThread(TAG,
2585                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2586        mHandlerThread.start();
2587        mHandler = new MainHandler(mHandlerThread.getLooper());
2588        mUiHandler = new UiHandler();
2589
2590        /* static; one-time init here */
2591        if (sKillHandler == null) {
2592            sKillThread = new ServiceThread(TAG + ":kill",
2593                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2594            sKillThread.start();
2595            sKillHandler = new KillHandler(sKillThread.getLooper());
2596        }
2597
2598        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2599                "foreground", BROADCAST_FG_TIMEOUT, false);
2600        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2601                "background", BROADCAST_BG_TIMEOUT, true);
2602        mBroadcastQueues[0] = mFgBroadcastQueue;
2603        mBroadcastQueues[1] = mBgBroadcastQueue;
2604
2605        mServices = new ActiveServices(this);
2606        mProviderMap = new ProviderMap(this);
2607        mAppErrors = new AppErrors(mContext, this);
2608
2609        // TODO: Move creation of battery stats service outside of activity manager service.
2610        File dataDir = Environment.getDataDirectory();
2611        File systemDir = new File(dataDir, "system");
2612        systemDir.mkdirs();
2613        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2614        mBatteryStatsService.getActiveStatistics().readLocked();
2615        mBatteryStatsService.scheduleWriteToDisk();
2616        mOnBattery = DEBUG_POWER ? true
2617                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2618        mBatteryStatsService.getActiveStatistics().setCallback(this);
2619
2620        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2621
2622        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2623        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2624                new IAppOpsCallback.Stub() {
2625                    @Override public void opChanged(int op, int uid, String packageName) {
2626                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2627                            if (mAppOpsService.checkOperation(op, uid, packageName)
2628                                    != AppOpsManager.MODE_ALLOWED) {
2629                                runInBackgroundDisabled(uid);
2630                            }
2631                        }
2632                    }
2633                });
2634
2635        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2636
2637        mUserController = new UserController(this);
2638
2639        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2640            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2641
2642        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2643
2644        mConfiguration.setToDefaults();
2645        mConfiguration.setLocales(LocaleList.getDefault());
2646
2647        mConfigurationSeq = mConfiguration.seq = 1;
2648        mProcessCpuTracker.init();
2649
2650        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2651        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2652        mStackSupervisor = new ActivityStackSupervisor(this);
2653        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2654        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2655
2656        mProcessCpuThread = new Thread("CpuTracker") {
2657            @Override
2658            public void run() {
2659                while (true) {
2660                    try {
2661                        try {
2662                            synchronized(this) {
2663                                final long now = SystemClock.uptimeMillis();
2664                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2665                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2666                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2667                                //        + ", write delay=" + nextWriteDelay);
2668                                if (nextWriteDelay < nextCpuDelay) {
2669                                    nextCpuDelay = nextWriteDelay;
2670                                }
2671                                if (nextCpuDelay > 0) {
2672                                    mProcessCpuMutexFree.set(true);
2673                                    this.wait(nextCpuDelay);
2674                                }
2675                            }
2676                        } catch (InterruptedException e) {
2677                        }
2678                        updateCpuStatsNow();
2679                    } catch (Exception e) {
2680                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2681                    }
2682                }
2683            }
2684        };
2685
2686        Watchdog.getInstance().addMonitor(this);
2687        Watchdog.getInstance().addThread(mHandler);
2688    }
2689
2690    public void setSystemServiceManager(SystemServiceManager mgr) {
2691        mSystemServiceManager = mgr;
2692    }
2693
2694    public void setInstaller(Installer installer) {
2695        mInstaller = installer;
2696    }
2697
2698    private void start() {
2699        Process.removeAllProcessGroups();
2700        mProcessCpuThread.start();
2701
2702        mBatteryStatsService.publish(mContext);
2703        mAppOpsService.publish(mContext);
2704        Slog.d("AppOps", "AppOpsService published");
2705        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2706    }
2707
2708    void onUserStoppedLocked(int userId) {
2709        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2710    }
2711
2712    public void initPowerManagement() {
2713        mStackSupervisor.initPowerManagement();
2714        mBatteryStatsService.initPowerManagement();
2715        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2716        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2717        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2718        mVoiceWakeLock.setReferenceCounted(false);
2719    }
2720
2721    @Override
2722    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2723            throws RemoteException {
2724        if (code == SYSPROPS_TRANSACTION) {
2725            // We need to tell all apps about the system property change.
2726            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2727            synchronized(this) {
2728                final int NP = mProcessNames.getMap().size();
2729                for (int ip=0; ip<NP; ip++) {
2730                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2731                    final int NA = apps.size();
2732                    for (int ia=0; ia<NA; ia++) {
2733                        ProcessRecord app = apps.valueAt(ia);
2734                        if (app.thread != null) {
2735                            procs.add(app.thread.asBinder());
2736                        }
2737                    }
2738                }
2739            }
2740
2741            int N = procs.size();
2742            for (int i=0; i<N; i++) {
2743                Parcel data2 = Parcel.obtain();
2744                try {
2745                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2746                } catch (RemoteException e) {
2747                }
2748                data2.recycle();
2749            }
2750        }
2751        try {
2752            return super.onTransact(code, data, reply, flags);
2753        } catch (RuntimeException e) {
2754            // The activity manager only throws security exceptions, so let's
2755            // log all others.
2756            if (!(e instanceof SecurityException)) {
2757                Slog.wtf(TAG, "Activity Manager Crash", e);
2758            }
2759            throw e;
2760        }
2761    }
2762
2763    void updateCpuStats() {
2764        final long now = SystemClock.uptimeMillis();
2765        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2766            return;
2767        }
2768        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2769            synchronized (mProcessCpuThread) {
2770                mProcessCpuThread.notify();
2771            }
2772        }
2773    }
2774
2775    void updateCpuStatsNow() {
2776        synchronized (mProcessCpuTracker) {
2777            mProcessCpuMutexFree.set(false);
2778            final long now = SystemClock.uptimeMillis();
2779            boolean haveNewCpuStats = false;
2780
2781            if (MONITOR_CPU_USAGE &&
2782                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2783                mLastCpuTime.set(now);
2784                mProcessCpuTracker.update();
2785                if (mProcessCpuTracker.hasGoodLastStats()) {
2786                    haveNewCpuStats = true;
2787                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2788                    //Slog.i(TAG, "Total CPU usage: "
2789                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2790
2791                    // Slog the cpu usage if the property is set.
2792                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2793                        int user = mProcessCpuTracker.getLastUserTime();
2794                        int system = mProcessCpuTracker.getLastSystemTime();
2795                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2796                        int irq = mProcessCpuTracker.getLastIrqTime();
2797                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2798                        int idle = mProcessCpuTracker.getLastIdleTime();
2799
2800                        int total = user + system + iowait + irq + softIrq + idle;
2801                        if (total == 0) total = 1;
2802
2803                        EventLog.writeEvent(EventLogTags.CPU,
2804                                ((user+system+iowait+irq+softIrq) * 100) / total,
2805                                (user * 100) / total,
2806                                (system * 100) / total,
2807                                (iowait * 100) / total,
2808                                (irq * 100) / total,
2809                                (softIrq * 100) / total);
2810                    }
2811                }
2812            }
2813
2814            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2815            synchronized(bstats) {
2816                synchronized(mPidsSelfLocked) {
2817                    if (haveNewCpuStats) {
2818                        if (bstats.startAddingCpuLocked()) {
2819                            int totalUTime = 0;
2820                            int totalSTime = 0;
2821                            final int N = mProcessCpuTracker.countStats();
2822                            for (int i=0; i<N; i++) {
2823                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2824                                if (!st.working) {
2825                                    continue;
2826                                }
2827                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2828                                totalUTime += st.rel_utime;
2829                                totalSTime += st.rel_stime;
2830                                if (pr != null) {
2831                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2832                                    if (ps == null || !ps.isActive()) {
2833                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2834                                                pr.info.uid, pr.processName);
2835                                    }
2836                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2837                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2838                                } else {
2839                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2840                                    if (ps == null || !ps.isActive()) {
2841                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2842                                                bstats.mapUid(st.uid), st.name);
2843                                    }
2844                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2845                                }
2846                            }
2847                            final int userTime = mProcessCpuTracker.getLastUserTime();
2848                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2849                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2850                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2851                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2852                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2853                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2854                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2855                        }
2856                    }
2857                }
2858
2859                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2860                    mLastWriteTime = now;
2861                    mBatteryStatsService.scheduleWriteToDisk();
2862                }
2863            }
2864        }
2865    }
2866
2867    @Override
2868    public void batteryNeedsCpuUpdate() {
2869        updateCpuStatsNow();
2870    }
2871
2872    @Override
2873    public void batteryPowerChanged(boolean onBattery) {
2874        // When plugging in, update the CPU stats first before changing
2875        // the plug state.
2876        updateCpuStatsNow();
2877        synchronized (this) {
2878            synchronized(mPidsSelfLocked) {
2879                mOnBattery = DEBUG_POWER ? true : onBattery;
2880            }
2881        }
2882    }
2883
2884    @Override
2885    public void batterySendBroadcast(Intent intent) {
2886        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2887                AppOpsManager.OP_NONE, null, false, false,
2888                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2889    }
2890
2891    /**
2892     * Initialize the application bind args. These are passed to each
2893     * process when the bindApplication() IPC is sent to the process. They're
2894     * lazily setup to make sure the services are running when they're asked for.
2895     */
2896    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2897        if (mAppBindArgs == null) {
2898            mAppBindArgs = new HashMap<>();
2899
2900            // Isolated processes won't get this optimization, so that we don't
2901            // violate the rules about which services they have access to.
2902            if (!isolated) {
2903                // Setup the application init args
2904                mAppBindArgs.put("package", ServiceManager.getService("package"));
2905                mAppBindArgs.put("window", ServiceManager.getService("window"));
2906                mAppBindArgs.put(Context.ALARM_SERVICE,
2907                        ServiceManager.getService(Context.ALARM_SERVICE));
2908            }
2909        }
2910        return mAppBindArgs;
2911    }
2912
2913    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2914        if (r == null || mFocusedActivity == r) {
2915            return false;
2916        }
2917
2918        if (!r.isFocusable()) {
2919            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2920            return false;
2921        }
2922
2923        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2924
2925        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2926        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2927                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2928        mDoingSetFocusedActivity = true;
2929
2930        final ActivityRecord last = mFocusedActivity;
2931        mFocusedActivity = r;
2932        if (r.task.isApplicationTask()) {
2933            if (mCurAppTimeTracker != r.appTimeTracker) {
2934                // We are switching app tracking.  Complete the current one.
2935                if (mCurAppTimeTracker != null) {
2936                    mCurAppTimeTracker.stop();
2937                    mHandler.obtainMessage(
2938                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2939                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2940                    mCurAppTimeTracker = null;
2941                }
2942                if (r.appTimeTracker != null) {
2943                    mCurAppTimeTracker = r.appTimeTracker;
2944                    startTimeTrackingFocusedActivityLocked();
2945                }
2946            } else {
2947                startTimeTrackingFocusedActivityLocked();
2948            }
2949        } else {
2950            r.appTimeTracker = null;
2951        }
2952        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2953        // TODO: Probably not, because we don't want to resume voice on switching
2954        // back to this activity
2955        if (r.task.voiceInteractor != null) {
2956            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2957        } else {
2958            finishRunningVoiceLocked();
2959            IVoiceInteractionSession session;
2960            if (last != null && ((session = last.task.voiceSession) != null
2961                    || (session = last.voiceSession) != null)) {
2962                // We had been in a voice interaction session, but now focused has
2963                // move to something different.  Just finish the session, we can't
2964                // return to it and retain the proper state and synchronization with
2965                // the voice interaction service.
2966                finishVoiceTask(session);
2967            }
2968        }
2969        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2970            mWindowManager.setFocusedApp(r.appToken, true);
2971        }
2972        applyUpdateLockStateLocked(r);
2973        applyUpdateVrModeLocked(r);
2974        if (mFocusedActivity.userId != mLastFocusedUserId) {
2975            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2976            mHandler.obtainMessage(
2977                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2978            mLastFocusedUserId = mFocusedActivity.userId;
2979        }
2980
2981        // Log a warning if the focused app is changed during the process. This could
2982        // indicate a problem of the focus setting logic!
2983        if (mFocusedActivity != r) Slog.w(TAG,
2984                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2985        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2986
2987        EventLogTags.writeAmFocusedActivity(
2988                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2989                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2990                reason);
2991        return true;
2992    }
2993
2994    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2995        if (mFocusedActivity != goingAway) {
2996            return;
2997        }
2998
2999        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3000        if (focusedStack != null) {
3001            final ActivityRecord top = focusedStack.topActivity();
3002            if (top != null && top.userId != mLastFocusedUserId) {
3003                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3004                mHandler.sendMessage(
3005                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3006                mLastFocusedUserId = top.userId;
3007            }
3008        }
3009
3010        // Try to move focus to another activity if possible.
3011        if (setFocusedActivityLocked(
3012                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3013            return;
3014        }
3015
3016        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3017                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3018        mFocusedActivity = null;
3019        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3020    }
3021
3022    @Override
3023    public void setFocusedStack(int stackId) {
3024        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3025        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3026        final long callingId = Binder.clearCallingIdentity();
3027        try {
3028            synchronized (this) {
3029                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3030                if (stack == null) {
3031                    return;
3032                }
3033                final ActivityRecord r = stack.topRunningActivityLocked();
3034                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3035                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3036                }
3037            }
3038        } finally {
3039            Binder.restoreCallingIdentity(callingId);
3040        }
3041    }
3042
3043    @Override
3044    public void setFocusedTask(int taskId) {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3046        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3047        final long callingId = Binder.clearCallingIdentity();
3048        try {
3049            synchronized (this) {
3050                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3051                if (task == null) {
3052                    return;
3053                }
3054                final ActivityRecord r = task.topRunningActivityLocked();
3055                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3056                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3057                }
3058            }
3059        } finally {
3060            Binder.restoreCallingIdentity(callingId);
3061        }
3062    }
3063
3064    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3065    @Override
3066    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3067        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3068        synchronized (this) {
3069            if (listener != null) {
3070                mTaskStackListeners.register(listener);
3071            }
3072        }
3073    }
3074
3075    @Override
3076    public void notifyActivityDrawn(IBinder token) {
3077        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3078        synchronized (this) {
3079            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3080            if (r != null) {
3081                r.task.stack.notifyActivityDrawnLocked(r);
3082            }
3083        }
3084    }
3085
3086    final void applyUpdateLockStateLocked(ActivityRecord r) {
3087        // Modifications to the UpdateLock state are done on our handler, outside
3088        // the activity manager's locks.  The new state is determined based on the
3089        // state *now* of the relevant activity record.  The object is passed to
3090        // the handler solely for logging detail, not to be consulted/modified.
3091        final boolean nextState = r != null && r.immersive;
3092        mHandler.sendMessage(
3093                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3094    }
3095
3096    final void applyUpdateVrModeLocked(ActivityRecord r) {
3097        mHandler.sendMessage(
3098                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3099    }
3100
3101    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3102        mHandler.sendMessage(
3103                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3104    }
3105
3106    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3107            ComponentName callingPackage, boolean immediate) {
3108        VrManagerInternal vrService =
3109                LocalServices.getService(VrManagerInternal.class);
3110        if (immediate) {
3111            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3112        } else {
3113            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3114        }
3115    }
3116
3117    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3118        Message msg = Message.obtain();
3119        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3120        msg.obj = r.task.askedCompatMode ? null : r;
3121        mUiHandler.sendMessage(msg);
3122    }
3123
3124    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3125        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3126                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3127            final Message msg = Message.obtain();
3128            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3129            msg.obj = r;
3130            mUiHandler.sendMessage(msg);
3131        }
3132    }
3133
3134    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3135            String what, Object obj, ProcessRecord srcApp) {
3136        app.lastActivityTime = now;
3137
3138        if (app.activities.size() > 0) {
3139            // Don't want to touch dependent processes that are hosting activities.
3140            return index;
3141        }
3142
3143        int lrui = mLruProcesses.lastIndexOf(app);
3144        if (lrui < 0) {
3145            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3146                    + what + " " + obj + " from " + srcApp);
3147            return index;
3148        }
3149
3150        if (lrui >= index) {
3151            // Don't want to cause this to move dependent processes *back* in the
3152            // list as if they were less frequently used.
3153            return index;
3154        }
3155
3156        if (lrui >= mLruProcessActivityStart) {
3157            // Don't want to touch dependent processes that are hosting activities.
3158            return index;
3159        }
3160
3161        mLruProcesses.remove(lrui);
3162        if (index > 0) {
3163            index--;
3164        }
3165        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3166                + " in LRU list: " + app);
3167        mLruProcesses.add(index, app);
3168        return index;
3169    }
3170
3171    static void killProcessGroup(int uid, int pid) {
3172        if (sKillHandler != null) {
3173            sKillHandler.sendMessage(
3174                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3175        } else {
3176            Slog.w(TAG, "Asked to kill process group before system bringup!");
3177            Process.killProcessGroup(uid, pid);
3178        }
3179    }
3180
3181    final void removeLruProcessLocked(ProcessRecord app) {
3182        int lrui = mLruProcesses.lastIndexOf(app);
3183        if (lrui >= 0) {
3184            if (!app.killed) {
3185                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3186                Process.killProcessQuiet(app.pid);
3187                killProcessGroup(app.uid, app.pid);
3188            }
3189            if (lrui <= mLruProcessActivityStart) {
3190                mLruProcessActivityStart--;
3191            }
3192            if (lrui <= mLruProcessServiceStart) {
3193                mLruProcessServiceStart--;
3194            }
3195            mLruProcesses.remove(lrui);
3196        }
3197    }
3198
3199    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3200            ProcessRecord client) {
3201        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3202                || app.treatLikeActivity;
3203        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3204        if (!activityChange && hasActivity) {
3205            // The process has activities, so we are only allowing activity-based adjustments
3206            // to move it.  It should be kept in the front of the list with other
3207            // processes that have activities, and we don't want those to change their
3208            // order except due to activity operations.
3209            return;
3210        }
3211
3212        mLruSeq++;
3213        final long now = SystemClock.uptimeMillis();
3214        app.lastActivityTime = now;
3215
3216        // First a quick reject: if the app is already at the position we will
3217        // put it, then there is nothing to do.
3218        if (hasActivity) {
3219            final int N = mLruProcesses.size();
3220            if (N > 0 && mLruProcesses.get(N-1) == app) {
3221                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3222                return;
3223            }
3224        } else {
3225            if (mLruProcessServiceStart > 0
3226                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3227                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3228                return;
3229            }
3230        }
3231
3232        int lrui = mLruProcesses.lastIndexOf(app);
3233
3234        if (app.persistent && lrui >= 0) {
3235            // We don't care about the position of persistent processes, as long as
3236            // they are in the list.
3237            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3238            return;
3239        }
3240
3241        /* In progress: compute new position first, so we can avoid doing work
3242           if the process is not actually going to move.  Not yet working.
3243        int addIndex;
3244        int nextIndex;
3245        boolean inActivity = false, inService = false;
3246        if (hasActivity) {
3247            // Process has activities, put it at the very tipsy-top.
3248            addIndex = mLruProcesses.size();
3249            nextIndex = mLruProcessServiceStart;
3250            inActivity = true;
3251        } else if (hasService) {
3252            // Process has services, put it at the top of the service list.
3253            addIndex = mLruProcessActivityStart;
3254            nextIndex = mLruProcessServiceStart;
3255            inActivity = true;
3256            inService = true;
3257        } else  {
3258            // Process not otherwise of interest, it goes to the top of the non-service area.
3259            addIndex = mLruProcessServiceStart;
3260            if (client != null) {
3261                int clientIndex = mLruProcesses.lastIndexOf(client);
3262                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3263                        + app);
3264                if (clientIndex >= 0 && addIndex > clientIndex) {
3265                    addIndex = clientIndex;
3266                }
3267            }
3268            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3269        }
3270
3271        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3272                + mLruProcessActivityStart + "): " + app);
3273        */
3274
3275        if (lrui >= 0) {
3276            if (lrui < mLruProcessActivityStart) {
3277                mLruProcessActivityStart--;
3278            }
3279            if (lrui < mLruProcessServiceStart) {
3280                mLruProcessServiceStart--;
3281            }
3282            /*
3283            if (addIndex > lrui) {
3284                addIndex--;
3285            }
3286            if (nextIndex > lrui) {
3287                nextIndex--;
3288            }
3289            */
3290            mLruProcesses.remove(lrui);
3291        }
3292
3293        /*
3294        mLruProcesses.add(addIndex, app);
3295        if (inActivity) {
3296            mLruProcessActivityStart++;
3297        }
3298        if (inService) {
3299            mLruProcessActivityStart++;
3300        }
3301        */
3302
3303        int nextIndex;
3304        if (hasActivity) {
3305            final int N = mLruProcesses.size();
3306            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3307                // Process doesn't have activities, but has clients with
3308                // activities...  move it up, but one below the top (the top
3309                // should always have a real activity).
3310                if (DEBUG_LRU) Slog.d(TAG_LRU,
3311                        "Adding to second-top of LRU activity list: " + app);
3312                mLruProcesses.add(N - 1, app);
3313                // To keep it from spamming the LRU list (by making a bunch of clients),
3314                // we will push down any other entries owned by the app.
3315                final int uid = app.info.uid;
3316                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3317                    ProcessRecord subProc = mLruProcesses.get(i);
3318                    if (subProc.info.uid == uid) {
3319                        // We want to push this one down the list.  If the process after
3320                        // it is for the same uid, however, don't do so, because we don't
3321                        // want them internally to be re-ordered.
3322                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3323                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3324                                    "Pushing uid " + uid + " swapping at " + i + ": "
3325                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3326                            ProcessRecord tmp = mLruProcesses.get(i);
3327                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3328                            mLruProcesses.set(i - 1, tmp);
3329                            i--;
3330                        }
3331                    } else {
3332                        // A gap, we can stop here.
3333                        break;
3334                    }
3335                }
3336            } else {
3337                // Process has activities, put it at the very tipsy-top.
3338                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3339                mLruProcesses.add(app);
3340            }
3341            nextIndex = mLruProcessServiceStart;
3342        } else if (hasService) {
3343            // Process has services, put it at the top of the service list.
3344            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3345            mLruProcesses.add(mLruProcessActivityStart, app);
3346            nextIndex = mLruProcessServiceStart;
3347            mLruProcessActivityStart++;
3348        } else  {
3349            // Process not otherwise of interest, it goes to the top of the non-service area.
3350            int index = mLruProcessServiceStart;
3351            if (client != null) {
3352                // If there is a client, don't allow the process to be moved up higher
3353                // in the list than that client.
3354                int clientIndex = mLruProcesses.lastIndexOf(client);
3355                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3356                        + " when updating " + app);
3357                if (clientIndex <= lrui) {
3358                    // Don't allow the client index restriction to push it down farther in the
3359                    // list than it already is.
3360                    clientIndex = lrui;
3361                }
3362                if (clientIndex >= 0 && index > clientIndex) {
3363                    index = clientIndex;
3364                }
3365            }
3366            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3367            mLruProcesses.add(index, app);
3368            nextIndex = index-1;
3369            mLruProcessActivityStart++;
3370            mLruProcessServiceStart++;
3371        }
3372
3373        // If the app is currently using a content provider or service,
3374        // bump those processes as well.
3375        for (int j=app.connections.size()-1; j>=0; j--) {
3376            ConnectionRecord cr = app.connections.valueAt(j);
3377            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3378                    && cr.binding.service.app != null
3379                    && cr.binding.service.app.lruSeq != mLruSeq
3380                    && !cr.binding.service.app.persistent) {
3381                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3382                        "service connection", cr, app);
3383            }
3384        }
3385        for (int j=app.conProviders.size()-1; j>=0; j--) {
3386            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3387            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3388                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3389                        "provider reference", cpr, app);
3390            }
3391        }
3392    }
3393
3394    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3395        if (uid == Process.SYSTEM_UID) {
3396            // The system gets to run in any process.  If there are multiple
3397            // processes with the same uid, just pick the first (this
3398            // should never happen).
3399            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3400            if (procs == null) return null;
3401            final int procCount = procs.size();
3402            for (int i = 0; i < procCount; i++) {
3403                final int procUid = procs.keyAt(i);
3404                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3405                    // Don't use an app process or different user process for system component.
3406                    continue;
3407                }
3408                return procs.valueAt(i);
3409            }
3410        }
3411        ProcessRecord proc = mProcessNames.get(processName, uid);
3412        if (false && proc != null && !keepIfLarge
3413                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3414                && proc.lastCachedPss >= 4000) {
3415            // Turn this condition on to cause killing to happen regularly, for testing.
3416            if (proc.baseProcessTracker != null) {
3417                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3418            }
3419            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3420        } else if (proc != null && !keepIfLarge
3421                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3422                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3423            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3424            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3425                if (proc.baseProcessTracker != null) {
3426                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3427                }
3428                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3429            }
3430        }
3431        return proc;
3432    }
3433
3434    void notifyPackageUse(String packageName, int reason) {
3435        IPackageManager pm = AppGlobals.getPackageManager();
3436        try {
3437            pm.notifyPackageUse(packageName, reason);
3438        } catch (RemoteException e) {
3439        }
3440    }
3441
3442    boolean isNextTransitionForward() {
3443        int transit = mWindowManager.getPendingAppTransition();
3444        return transit == TRANSIT_ACTIVITY_OPEN
3445                || transit == TRANSIT_TASK_OPEN
3446                || transit == TRANSIT_TASK_TO_FRONT;
3447    }
3448
3449    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3450            String processName, String abiOverride, int uid, Runnable crashHandler) {
3451        synchronized(this) {
3452            ApplicationInfo info = new ApplicationInfo();
3453            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3454            // For isolated processes, the former contains the parent's uid and the latter the
3455            // actual uid of the isolated process.
3456            // In the special case introduced by this method (which is, starting an isolated
3457            // process directly from the SystemServer without an actual parent app process) the
3458            // closest thing to a parent's uid is SYSTEM_UID.
3459            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3460            // the |isolated| logic in the ProcessRecord constructor.
3461            info.uid = Process.SYSTEM_UID;
3462            info.processName = processName;
3463            info.className = entryPoint;
3464            info.packageName = "android";
3465            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3466                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3467                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3468                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3469                    crashHandler);
3470            return proc != null ? proc.pid : 0;
3471        }
3472    }
3473
3474    final ProcessRecord startProcessLocked(String processName,
3475            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3476            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3477            boolean isolated, boolean keepIfLarge) {
3478        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3479                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3480                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3481                null /* crashHandler */);
3482    }
3483
3484    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3485            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3486            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3487            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3488        long startTime = SystemClock.elapsedRealtime();
3489        ProcessRecord app;
3490        if (!isolated) {
3491            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3492            checkTime(startTime, "startProcess: after getProcessRecord");
3493
3494            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3495                // If we are in the background, then check to see if this process
3496                // is bad.  If so, we will just silently fail.
3497                if (mAppErrors.isBadProcessLocked(info)) {
3498                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3499                            + "/" + info.processName);
3500                    return null;
3501                }
3502            } else {
3503                // When the user is explicitly starting a process, then clear its
3504                // crash count so that we won't make it bad until they see at
3505                // least one crash dialog again, and make the process good again
3506                // if it had been bad.
3507                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3508                        + "/" + info.processName);
3509                mAppErrors.resetProcessCrashTimeLocked(info);
3510                if (mAppErrors.isBadProcessLocked(info)) {
3511                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3512                            UserHandle.getUserId(info.uid), info.uid,
3513                            info.processName);
3514                    mAppErrors.clearBadProcessLocked(info);
3515                    if (app != null) {
3516                        app.bad = false;
3517                    }
3518                }
3519            }
3520        } else {
3521            // If this is an isolated process, it can't re-use an existing process.
3522            app = null;
3523        }
3524
3525        // app launch boost for big.little configurations
3526        // use cpusets to migrate freshly launched tasks to big cores
3527        nativeMigrateToBoost();
3528        mIsBoosted = true;
3529        mBoostStartTime = SystemClock.uptimeMillis();
3530        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3531        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3532
3533        // We don't have to do anything more if:
3534        // (1) There is an existing application record; and
3535        // (2) The caller doesn't think it is dead, OR there is no thread
3536        //     object attached to it so we know it couldn't have crashed; and
3537        // (3) There is a pid assigned to it, so it is either starting or
3538        //     already running.
3539        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3540                + " app=" + app + " knownToBeDead=" + knownToBeDead
3541                + " thread=" + (app != null ? app.thread : null)
3542                + " pid=" + (app != null ? app.pid : -1));
3543        if (app != null && app.pid > 0) {
3544            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3545                // We already have the app running, or are waiting for it to
3546                // come up (we have a pid but not yet its thread), so keep it.
3547                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3548                // If this is a new package in the process, add the package to the list
3549                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3550                checkTime(startTime, "startProcess: done, added package to proc");
3551                return app;
3552            }
3553
3554            // An application record is attached to a previous process,
3555            // clean it up now.
3556            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3557            checkTime(startTime, "startProcess: bad proc running, killing");
3558            killProcessGroup(app.uid, app.pid);
3559            handleAppDiedLocked(app, true, true);
3560            checkTime(startTime, "startProcess: done killing old proc");
3561        }
3562
3563        String hostingNameStr = hostingName != null
3564                ? hostingName.flattenToShortString() : null;
3565
3566        if (app == null) {
3567            checkTime(startTime, "startProcess: creating new process record");
3568            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3569            if (app == null) {
3570                Slog.w(TAG, "Failed making new process record for "
3571                        + processName + "/" + info.uid + " isolated=" + isolated);
3572                return null;
3573            }
3574            app.crashHandler = crashHandler;
3575            checkTime(startTime, "startProcess: done creating new process record");
3576        } else {
3577            // If this is a new package in the process, add the package to the list
3578            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3579            checkTime(startTime, "startProcess: added package to existing proc");
3580        }
3581
3582        // If the system is not ready yet, then hold off on starting this
3583        // process until it is.
3584        if (!mProcessesReady
3585                && !isAllowedWhileBooting(info)
3586                && !allowWhileBooting) {
3587            if (!mProcessesOnHold.contains(app)) {
3588                mProcessesOnHold.add(app);
3589            }
3590            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3591                    "System not ready, putting on hold: " + app);
3592            checkTime(startTime, "startProcess: returning with proc on hold");
3593            return app;
3594        }
3595
3596        checkTime(startTime, "startProcess: stepping in to startProcess");
3597        startProcessLocked(
3598                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3599        checkTime(startTime, "startProcess: done starting proc!");
3600        return (app.pid != 0) ? app : null;
3601    }
3602
3603    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3604        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3605    }
3606
3607    private final void startProcessLocked(ProcessRecord app,
3608            String hostingType, String hostingNameStr) {
3609        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3610                null /* entryPoint */, null /* entryPointArgs */);
3611    }
3612
3613    private final void startProcessLocked(ProcessRecord app, String hostingType,
3614            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3615        long startTime = SystemClock.elapsedRealtime();
3616        if (app.pid > 0 && app.pid != MY_PID) {
3617            checkTime(startTime, "startProcess: removing from pids map");
3618            synchronized (mPidsSelfLocked) {
3619                mPidsSelfLocked.remove(app.pid);
3620                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3621            }
3622            checkTime(startTime, "startProcess: done removing from pids map");
3623            app.setPid(0);
3624        }
3625
3626        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3627                "startProcessLocked removing on hold: " + app);
3628        mProcessesOnHold.remove(app);
3629
3630        checkTime(startTime, "startProcess: starting to update cpu stats");
3631        updateCpuStats();
3632        checkTime(startTime, "startProcess: done updating cpu stats");
3633
3634        try {
3635            try {
3636                final int userId = UserHandle.getUserId(app.uid);
3637                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3638            } catch (RemoteException e) {
3639                throw e.rethrowAsRuntimeException();
3640            }
3641
3642            int uid = app.uid;
3643            int[] gids = null;
3644            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3645            if (!app.isolated) {
3646                int[] permGids = null;
3647                try {
3648                    checkTime(startTime, "startProcess: getting gids from package manager");
3649                    final IPackageManager pm = AppGlobals.getPackageManager();
3650                    permGids = pm.getPackageGids(app.info.packageName,
3651                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3652                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3653                            MountServiceInternal.class);
3654                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3655                            app.info.packageName);
3656                } catch (RemoteException e) {
3657                    throw e.rethrowAsRuntimeException();
3658                }
3659
3660                /*
3661                 * Add shared application and profile GIDs so applications can share some
3662                 * resources like shared libraries and access user-wide resources
3663                 */
3664                if (ArrayUtils.isEmpty(permGids)) {
3665                    gids = new int[2];
3666                } else {
3667                    gids = new int[permGids.length + 2];
3668                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3669                }
3670                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3671                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3672            }
3673            checkTime(startTime, "startProcess: building args");
3674            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3675                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3676                        && mTopComponent != null
3677                        && app.processName.equals(mTopComponent.getPackageName())) {
3678                    uid = 0;
3679                }
3680                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3681                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3682                    uid = 0;
3683                }
3684            }
3685            int debugFlags = 0;
3686            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3687                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3688                // Also turn on CheckJNI for debuggable apps. It's quite
3689                // awkward to turn on otherwise.
3690                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3691            }
3692            // Run the app in safe mode if its manifest requests so or the
3693            // system is booted in safe mode.
3694            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3695                mSafeMode == true) {
3696                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3697            }
3698            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3699                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3700            }
3701            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3702            if ("true".equals(genDebugInfoProperty)) {
3703                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3704            }
3705            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3706                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3707            }
3708            if ("1".equals(SystemProperties.get("debug.assert"))) {
3709                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3710            }
3711            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3712                // Enable all debug flags required by the native debugger.
3713                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3714                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3715                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3716                mNativeDebuggingApp = null;
3717            }
3718
3719            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3720            if (requiredAbi == null) {
3721                requiredAbi = Build.SUPPORTED_ABIS[0];
3722            }
3723
3724            String instructionSet = null;
3725            if (app.info.primaryCpuAbi != null) {
3726                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3727            }
3728
3729            app.gids = gids;
3730            app.requiredAbi = requiredAbi;
3731            app.instructionSet = instructionSet;
3732
3733            // Start the process.  It will either succeed and return a result containing
3734            // the PID of the new process, or else throw a RuntimeException.
3735            boolean isActivityProcess = (entryPoint == null);
3736            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3737            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3738                    app.processName);
3739            checkTime(startTime, "startProcess: asking zygote to start proc");
3740            Process.ProcessStartResult startResult = Process.start(entryPoint,
3741                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3742                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3743                    app.info.dataDir, entryPointArgs);
3744            checkTime(startTime, "startProcess: returned from zygote!");
3745            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3746
3747            if (app.isolated) {
3748                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3749            }
3750            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3751            checkTime(startTime, "startProcess: done updating battery stats");
3752
3753            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3754                    UserHandle.getUserId(uid), startResult.pid, uid,
3755                    app.processName, hostingType,
3756                    hostingNameStr != null ? hostingNameStr : "");
3757
3758            try {
3759                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3760                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3761            } catch (RemoteException ex) {
3762                // Ignore
3763            }
3764
3765            if (app.persistent) {
3766                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3767            }
3768
3769            checkTime(startTime, "startProcess: building log message");
3770            StringBuilder buf = mStringBuilder;
3771            buf.setLength(0);
3772            buf.append("Start proc ");
3773            buf.append(startResult.pid);
3774            buf.append(':');
3775            buf.append(app.processName);
3776            buf.append('/');
3777            UserHandle.formatUid(buf, uid);
3778            if (!isActivityProcess) {
3779                buf.append(" [");
3780                buf.append(entryPoint);
3781                buf.append("]");
3782            }
3783            buf.append(" for ");
3784            buf.append(hostingType);
3785            if (hostingNameStr != null) {
3786                buf.append(" ");
3787                buf.append(hostingNameStr);
3788            }
3789            Slog.i(TAG, buf.toString());
3790            app.setPid(startResult.pid);
3791            app.usingWrapper = startResult.usingWrapper;
3792            app.removed = false;
3793            app.killed = false;
3794            app.killedByAm = false;
3795            checkTime(startTime, "startProcess: starting to update pids map");
3796            synchronized (mPidsSelfLocked) {
3797                this.mPidsSelfLocked.put(startResult.pid, app);
3798                if (isActivityProcess) {
3799                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3800                    msg.obj = app;
3801                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3802                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3803                }
3804            }
3805            checkTime(startTime, "startProcess: done updating pids map");
3806        } catch (RuntimeException e) {
3807            Slog.e(TAG, "Failure starting process " + app.processName, e);
3808
3809            // Something went very wrong while trying to start this process; one
3810            // common case is when the package is frozen due to an active
3811            // upgrade. To recover, clean up any active bookkeeping related to
3812            // starting this process. (We already invoked this method once when
3813            // the package was initially frozen through KILL_APPLICATION_MSG, so
3814            // it doesn't hurt to use it again.)
3815            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3816                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3817        }
3818    }
3819
3820    void updateUsageStats(ActivityRecord component, boolean resumed) {
3821        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3822                "updateUsageStats: comp=" + component + "res=" + resumed);
3823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3824        if (resumed) {
3825            if (mUsageStatsService != null) {
3826                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3827                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3828            }
3829            synchronized (stats) {
3830                stats.noteActivityResumedLocked(component.app.uid);
3831            }
3832        } else {
3833            if (mUsageStatsService != null) {
3834                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3835                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3836            }
3837            synchronized (stats) {
3838                stats.noteActivityPausedLocked(component.app.uid);
3839            }
3840        }
3841    }
3842
3843    Intent getHomeIntent() {
3844        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3845        intent.setComponent(mTopComponent);
3846        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3847        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3848            intent.addCategory(Intent.CATEGORY_HOME);
3849        }
3850        return intent;
3851    }
3852
3853    boolean startHomeActivityLocked(int userId, String reason) {
3854        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3855                && mTopAction == null) {
3856            // We are running in factory test mode, but unable to find
3857            // the factory test app, so just sit around displaying the
3858            // error message and don't try to start anything.
3859            return false;
3860        }
3861        Intent intent = getHomeIntent();
3862        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3863        if (aInfo != null) {
3864            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3865            // Don't do this if the home app is currently being
3866            // instrumented.
3867            aInfo = new ActivityInfo(aInfo);
3868            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3869            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3870                    aInfo.applicationInfo.uid, true);
3871            if (app == null || app.instrumentationClass == null) {
3872                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3873                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3874            }
3875        } else {
3876            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3877        }
3878
3879        return true;
3880    }
3881
3882    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3883        ActivityInfo ai = null;
3884        ComponentName comp = intent.getComponent();
3885        try {
3886            if (comp != null) {
3887                // Factory test.
3888                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3889            } else {
3890                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3891                        intent,
3892                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3893                        flags, userId);
3894
3895                if (info != null) {
3896                    ai = info.activityInfo;
3897                }
3898            }
3899        } catch (RemoteException e) {
3900            // ignore
3901        }
3902
3903        return ai;
3904    }
3905
3906    /**
3907     * Starts the "new version setup screen" if appropriate.
3908     */
3909    void startSetupActivityLocked() {
3910        // Only do this once per boot.
3911        if (mCheckedForSetup) {
3912            return;
3913        }
3914
3915        // We will show this screen if the current one is a different
3916        // version than the last one shown, and we are not running in
3917        // low-level factory test mode.
3918        final ContentResolver resolver = mContext.getContentResolver();
3919        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3920                Settings.Global.getInt(resolver,
3921                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3922            mCheckedForSetup = true;
3923
3924            // See if we should be showing the platform update setup UI.
3925            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3926            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3927                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3928            if (!ris.isEmpty()) {
3929                final ResolveInfo ri = ris.get(0);
3930                String vers = ri.activityInfo.metaData != null
3931                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3932                        : null;
3933                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3934                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3935                            Intent.METADATA_SETUP_VERSION);
3936                }
3937                String lastVers = Settings.Secure.getString(
3938                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3939                if (vers != null && !vers.equals(lastVers)) {
3940                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3941                    intent.setComponent(new ComponentName(
3942                            ri.activityInfo.packageName, ri.activityInfo.name));
3943                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3944                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3945                            null, 0, 0, 0, null, false, false, null, null, null);
3946                }
3947            }
3948        }
3949    }
3950
3951    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3952        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3953    }
3954
3955    void enforceNotIsolatedCaller(String caller) {
3956        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3957            throw new SecurityException("Isolated process not allowed to call " + caller);
3958        }
3959    }
3960
3961    void enforceShellRestriction(String restriction, int userHandle) {
3962        if (Binder.getCallingUid() == Process.SHELL_UID) {
3963            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3964                throw new SecurityException("Shell does not have permission to access user "
3965                        + userHandle);
3966            }
3967        }
3968    }
3969
3970    @Override
3971    public int getFrontActivityScreenCompatMode() {
3972        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3973        synchronized (this) {
3974            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3975        }
3976    }
3977
3978    @Override
3979    public void setFrontActivityScreenCompatMode(int mode) {
3980        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3981                "setFrontActivityScreenCompatMode");
3982        synchronized (this) {
3983            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3984        }
3985    }
3986
3987    @Override
3988    public int getPackageScreenCompatMode(String packageName) {
3989        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3990        synchronized (this) {
3991            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3992        }
3993    }
3994
3995    @Override
3996    public void setPackageScreenCompatMode(String packageName, int mode) {
3997        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3998                "setPackageScreenCompatMode");
3999        synchronized (this) {
4000            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4001        }
4002    }
4003
4004    @Override
4005    public boolean getPackageAskScreenCompat(String packageName) {
4006        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4007        synchronized (this) {
4008            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4009        }
4010    }
4011
4012    @Override
4013    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4014        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4015                "setPackageAskScreenCompat");
4016        synchronized (this) {
4017            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4018        }
4019    }
4020
4021    private boolean hasUsageStatsPermission(String callingPackage) {
4022        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4023                Binder.getCallingUid(), callingPackage);
4024        if (mode == AppOpsManager.MODE_DEFAULT) {
4025            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4026                    == PackageManager.PERMISSION_GRANTED;
4027        }
4028        return mode == AppOpsManager.MODE_ALLOWED;
4029    }
4030
4031    @Override
4032    public int getPackageProcessState(String packageName, String callingPackage) {
4033        if (!hasUsageStatsPermission(callingPackage)) {
4034            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4035                    "getPackageProcessState");
4036        }
4037
4038        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4039        synchronized (this) {
4040            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4041                final ProcessRecord proc = mLruProcesses.get(i);
4042                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4043                        || procState > proc.setProcState) {
4044                    boolean found = false;
4045                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4046                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4047                            procState = proc.setProcState;
4048                            found = true;
4049                        }
4050                    }
4051                    if (proc.pkgDeps != null && !found) {
4052                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4053                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4054                                procState = proc.setProcState;
4055                                break;
4056                            }
4057                        }
4058                    }
4059                }
4060            }
4061        }
4062        return procState;
4063    }
4064
4065    @Override
4066    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4067        synchronized (this) {
4068            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4069            if (app == null) {
4070                return false;
4071            }
4072            if (app.trimMemoryLevel < level && app.thread != null &&
4073                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4074                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4075                try {
4076                    app.thread.scheduleTrimMemory(level);
4077                    app.trimMemoryLevel = level;
4078                    return true;
4079                } catch (RemoteException e) {
4080                    // Fallthrough to failure case.
4081                }
4082            }
4083        }
4084        return false;
4085    }
4086
4087    private void dispatchProcessesChanged() {
4088        int N;
4089        synchronized (this) {
4090            N = mPendingProcessChanges.size();
4091            if (mActiveProcessChanges.length < N) {
4092                mActiveProcessChanges = new ProcessChangeItem[N];
4093            }
4094            mPendingProcessChanges.toArray(mActiveProcessChanges);
4095            mPendingProcessChanges.clear();
4096            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4097                    "*** Delivering " + N + " process changes");
4098        }
4099
4100        int i = mProcessObservers.beginBroadcast();
4101        while (i > 0) {
4102            i--;
4103            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4104            if (observer != null) {
4105                try {
4106                    for (int j=0; j<N; j++) {
4107                        ProcessChangeItem item = mActiveProcessChanges[j];
4108                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4109                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4110                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4111                                    + item.uid + ": " + item.foregroundActivities);
4112                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4113                                    item.foregroundActivities);
4114                        }
4115                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4116                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4117                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4118                                    + ": " + item.processState);
4119                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4120                        }
4121                    }
4122                } catch (RemoteException e) {
4123                }
4124            }
4125        }
4126        mProcessObservers.finishBroadcast();
4127
4128        synchronized (this) {
4129            for (int j=0; j<N; j++) {
4130                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4131            }
4132        }
4133    }
4134
4135    private void dispatchProcessDied(int pid, int uid) {
4136        int i = mProcessObservers.beginBroadcast();
4137        while (i > 0) {
4138            i--;
4139            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4140            if (observer != null) {
4141                try {
4142                    observer.onProcessDied(pid, uid);
4143                } catch (RemoteException e) {
4144                }
4145            }
4146        }
4147        mProcessObservers.finishBroadcast();
4148    }
4149
4150    private void dispatchUidsChanged() {
4151        int N;
4152        synchronized (this) {
4153            N = mPendingUidChanges.size();
4154            if (mActiveUidChanges.length < N) {
4155                mActiveUidChanges = new UidRecord.ChangeItem[N];
4156            }
4157            for (int i=0; i<N; i++) {
4158                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4159                mActiveUidChanges[i] = change;
4160                if (change.uidRecord != null) {
4161                    change.uidRecord.pendingChange = null;
4162                    change.uidRecord = null;
4163                }
4164            }
4165            mPendingUidChanges.clear();
4166            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                    "*** Delivering " + N + " uid changes");
4168        }
4169
4170        if (mLocalPowerManager != null) {
4171            for (int j=0; j<N; j++) {
4172                UidRecord.ChangeItem item = mActiveUidChanges[j];
4173                if (item.change == UidRecord.CHANGE_GONE
4174                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4175                    mLocalPowerManager.uidGone(item.uid);
4176                } else {
4177                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4178                }
4179            }
4180        }
4181
4182        int i = mUidObservers.beginBroadcast();
4183        while (i > 0) {
4184            i--;
4185            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4186            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4187            if (observer != null) {
4188                try {
4189                    for (int j=0; j<N; j++) {
4190                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4191                        final int change = item.change;
4192                        UidRecord validateUid = null;
4193                        if (VALIDATE_UID_STATES && i == 0) {
4194                            validateUid = mValidateUids.get(item.uid);
4195                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4196                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4197                                validateUid = new UidRecord(item.uid);
4198                                mValidateUids.put(item.uid, validateUid);
4199                            }
4200                        }
4201                        if (change == UidRecord.CHANGE_IDLE
4202                                || change == UidRecord.CHANGE_GONE_IDLE) {
4203                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4204                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4205                                        "UID idle uid=" + item.uid);
4206                                observer.onUidIdle(item.uid);
4207                            }
4208                            if (VALIDATE_UID_STATES && i == 0) {
4209                                if (validateUid != null) {
4210                                    validateUid.idle = true;
4211                                }
4212                            }
4213                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4214                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4215                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4216                                        "UID active uid=" + item.uid);
4217                                observer.onUidActive(item.uid);
4218                            }
4219                            if (VALIDATE_UID_STATES && i == 0) {
4220                                validateUid.idle = false;
4221                            }
4222                        }
4223                        if (change == UidRecord.CHANGE_GONE
4224                                || change == UidRecord.CHANGE_GONE_IDLE) {
4225                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4226                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4227                                        "UID gone uid=" + item.uid);
4228                                observer.onUidGone(item.uid);
4229                            }
4230                            if (VALIDATE_UID_STATES && i == 0) {
4231                                if (validateUid != null) {
4232                                    mValidateUids.remove(item.uid);
4233                                }
4234                            }
4235                        } else {
4236                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4237                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4238                                        "UID CHANGED uid=" + item.uid
4239                                                + ": " + item.processState);
4240                                observer.onUidStateChanged(item.uid, item.processState);
4241                            }
4242                            if (VALIDATE_UID_STATES && i == 0) {
4243                                validateUid.curProcState = validateUid.setProcState
4244                                        = item.processState;
4245                            }
4246                        }
4247                    }
4248                } catch (RemoteException e) {
4249                }
4250            }
4251        }
4252        mUidObservers.finishBroadcast();
4253
4254        synchronized (this) {
4255            for (int j=0; j<N; j++) {
4256                mAvailUidChanges.add(mActiveUidChanges[j]);
4257            }
4258        }
4259    }
4260
4261    @Override
4262    public final int startActivity(IApplicationThread caller, String callingPackage,
4263            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4265        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4266                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4267                UserHandle.getCallingUserId());
4268    }
4269
4270    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4271        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4272        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4273                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4274                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4275
4276        // TODO: Switch to user app stacks here.
4277        String mimeType = intent.getType();
4278        final Uri data = intent.getData();
4279        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4280            mimeType = getProviderMimeType(data, userId);
4281        }
4282        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4283
4284        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4285        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4286                null, 0, 0, null, null, null, null, false, userId, container, null);
4287    }
4288
4289    @Override
4290    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4291            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4292            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4293        enforceNotIsolatedCaller("startActivity");
4294        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4295                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4296        // TODO: Switch to user app stacks here.
4297        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4298                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4299                profilerInfo, null, null, bOptions, false, userId, null, null);
4300    }
4301
4302    @Override
4303    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4304            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4305            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4306            int userId) {
4307
4308        // This is very dangerous -- it allows you to perform a start activity (including
4309        // permission grants) as any app that may launch one of your own activities.  So
4310        // we will only allow this to be done from activities that are part of the core framework,
4311        // and then only when they are running as the system.
4312        final ActivityRecord sourceRecord;
4313        final int targetUid;
4314        final String targetPackage;
4315        synchronized (this) {
4316            if (resultTo == null) {
4317                throw new SecurityException("Must be called from an activity");
4318            }
4319            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4320            if (sourceRecord == null) {
4321                throw new SecurityException("Called with bad activity token: " + resultTo);
4322            }
4323            if (!sourceRecord.info.packageName.equals("android")) {
4324                throw new SecurityException(
4325                        "Must be called from an activity that is declared in the android package");
4326            }
4327            if (sourceRecord.app == null) {
4328                throw new SecurityException("Called without a process attached to activity");
4329            }
4330            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4331                // This is still okay, as long as this activity is running under the
4332                // uid of the original calling activity.
4333                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4334                    throw new SecurityException(
4335                            "Calling activity in uid " + sourceRecord.app.uid
4336                                    + " must be system uid or original calling uid "
4337                                    + sourceRecord.launchedFromUid);
4338                }
4339            }
4340            if (ignoreTargetSecurity) {
4341                if (intent.getComponent() == null) {
4342                    throw new SecurityException(
4343                            "Component must be specified with ignoreTargetSecurity");
4344                }
4345                if (intent.getSelector() != null) {
4346                    throw new SecurityException(
4347                            "Selector not allowed with ignoreTargetSecurity");
4348                }
4349            }
4350            targetUid = sourceRecord.launchedFromUid;
4351            targetPackage = sourceRecord.launchedFromPackage;
4352        }
4353
4354        if (userId == UserHandle.USER_NULL) {
4355            userId = UserHandle.getUserId(sourceRecord.app.uid);
4356        }
4357
4358        // TODO: Switch to user app stacks here.
4359        try {
4360            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4361                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4362                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4363            return ret;
4364        } catch (SecurityException e) {
4365            // XXX need to figure out how to propagate to original app.
4366            // A SecurityException here is generally actually a fault of the original
4367            // calling activity (such as a fairly granting permissions), so propagate it
4368            // back to them.
4369            /*
4370            StringBuilder msg = new StringBuilder();
4371            msg.append("While launching");
4372            msg.append(intent.toString());
4373            msg.append(": ");
4374            msg.append(e.getMessage());
4375            */
4376            throw e;
4377        }
4378    }
4379
4380    @Override
4381    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4382            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4383            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4384        enforceNotIsolatedCaller("startActivityAndWait");
4385        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4386                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4387        WaitResult res = new WaitResult();
4388        // TODO: Switch to user app stacks here.
4389        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4390                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4391                bOptions, false, userId, null, null);
4392        return res;
4393    }
4394
4395    @Override
4396    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4397            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4398            int startFlags, Configuration config, Bundle bOptions, int userId) {
4399        enforceNotIsolatedCaller("startActivityWithConfig");
4400        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4401                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4402        // TODO: Switch to user app stacks here.
4403        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4404                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4405                null, null, config, bOptions, false, userId, null, null);
4406        return ret;
4407    }
4408
4409    @Override
4410    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4411            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4412            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4413            throws TransactionTooLargeException {
4414        enforceNotIsolatedCaller("startActivityIntentSender");
4415        // Refuse possible leaked file descriptors
4416        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4417            throw new IllegalArgumentException("File descriptors passed in Intent");
4418        }
4419
4420        IIntentSender sender = intent.getTarget();
4421        if (!(sender instanceof PendingIntentRecord)) {
4422            throw new IllegalArgumentException("Bad PendingIntent object");
4423        }
4424
4425        PendingIntentRecord pir = (PendingIntentRecord)sender;
4426
4427        synchronized (this) {
4428            // If this is coming from the currently resumed activity, it is
4429            // effectively saying that app switches are allowed at this point.
4430            final ActivityStack stack = getFocusedStack();
4431            if (stack.mResumedActivity != null &&
4432                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4433                mAppSwitchesAllowedTime = 0;
4434            }
4435        }
4436        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4437                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4438        return ret;
4439    }
4440
4441    @Override
4442    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4443            Intent intent, String resolvedType, IVoiceInteractionSession session,
4444            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4445            Bundle bOptions, int userId) {
4446        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4447                != PackageManager.PERMISSION_GRANTED) {
4448            String msg = "Permission Denial: startVoiceActivity() from pid="
4449                    + Binder.getCallingPid()
4450                    + ", uid=" + Binder.getCallingUid()
4451                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4452            Slog.w(TAG, msg);
4453            throw new SecurityException(msg);
4454        }
4455        if (session == null || interactor == null) {
4456            throw new NullPointerException("null session or interactor");
4457        }
4458        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4459                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4460        // TODO: Switch to user app stacks here.
4461        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4462                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4463                null, bOptions, false, userId, null, null);
4464    }
4465
4466    @Override
4467    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4468            throws RemoteException {
4469        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4470        synchronized (this) {
4471            ActivityRecord activity = getFocusedStack().topActivity();
4472            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4473                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4474            }
4475            if (mRunningVoice != null || activity.task.voiceSession != null
4476                    || activity.voiceSession != null) {
4477                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4478                return;
4479            }
4480            if (activity.pendingVoiceInteractionStart) {
4481                Slog.w(TAG, "Pending start of voice interaction already.");
4482                return;
4483            }
4484            activity.pendingVoiceInteractionStart = true;
4485        }
4486        LocalServices.getService(VoiceInteractionManagerInternal.class)
4487                .startLocalVoiceInteraction(callingActivity, options);
4488    }
4489
4490    @Override
4491    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4492        LocalServices.getService(VoiceInteractionManagerInternal.class)
4493                .stopLocalVoiceInteraction(callingActivity);
4494    }
4495
4496    @Override
4497    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4498        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4499                .supportsLocalVoiceInteraction();
4500    }
4501
4502    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4503            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4504        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4505        if (activityToCallback == null) return;
4506        activityToCallback.setVoiceSessionLocked(voiceSession);
4507
4508        // Inform the activity
4509        try {
4510            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4511                    voiceInteractor);
4512            long token = Binder.clearCallingIdentity();
4513            try {
4514                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4515            } finally {
4516                Binder.restoreCallingIdentity(token);
4517            }
4518            // TODO: VI Should we cache the activity so that it's easier to find later
4519            // rather than scan through all the stacks and activities?
4520        } catch (RemoteException re) {
4521            activityToCallback.clearVoiceSessionLocked();
4522            // TODO: VI Should this terminate the voice session?
4523        }
4524    }
4525
4526    @Override
4527    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4528        synchronized (this) {
4529            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4530                if (keepAwake) {
4531                    mVoiceWakeLock.acquire();
4532                } else {
4533                    mVoiceWakeLock.release();
4534                }
4535            }
4536        }
4537    }
4538
4539    @Override
4540    public boolean startNextMatchingActivity(IBinder callingActivity,
4541            Intent intent, Bundle bOptions) {
4542        // Refuse possible leaked file descriptors
4543        if (intent != null && intent.hasFileDescriptors() == true) {
4544            throw new IllegalArgumentException("File descriptors passed in Intent");
4545        }
4546        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4547
4548        synchronized (this) {
4549            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4550            if (r == null) {
4551                ActivityOptions.abort(options);
4552                return false;
4553            }
4554            if (r.app == null || r.app.thread == null) {
4555                // The caller is not running...  d'oh!
4556                ActivityOptions.abort(options);
4557                return false;
4558            }
4559            intent = new Intent(intent);
4560            // The caller is not allowed to change the data.
4561            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4562            // And we are resetting to find the next component...
4563            intent.setComponent(null);
4564
4565            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4566
4567            ActivityInfo aInfo = null;
4568            try {
4569                List<ResolveInfo> resolves =
4570                    AppGlobals.getPackageManager().queryIntentActivities(
4571                            intent, r.resolvedType,
4572                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4573                            UserHandle.getCallingUserId()).getList();
4574
4575                // Look for the original activity in the list...
4576                final int N = resolves != null ? resolves.size() : 0;
4577                for (int i=0; i<N; i++) {
4578                    ResolveInfo rInfo = resolves.get(i);
4579                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4580                            && rInfo.activityInfo.name.equals(r.info.name)) {
4581                        // We found the current one...  the next matching is
4582                        // after it.
4583                        i++;
4584                        if (i<N) {
4585                            aInfo = resolves.get(i).activityInfo;
4586                        }
4587                        if (debug) {
4588                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4589                                    + "/" + r.info.name);
4590                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4591                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4592                        }
4593                        break;
4594                    }
4595                }
4596            } catch (RemoteException e) {
4597            }
4598
4599            if (aInfo == null) {
4600                // Nobody who is next!
4601                ActivityOptions.abort(options);
4602                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4603                return false;
4604            }
4605
4606            intent.setComponent(new ComponentName(
4607                    aInfo.applicationInfo.packageName, aInfo.name));
4608            intent.setFlags(intent.getFlags()&~(
4609                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4610                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4611                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4612                    Intent.FLAG_ACTIVITY_NEW_TASK));
4613
4614            // Okay now we need to start the new activity, replacing the
4615            // currently running activity.  This is a little tricky because
4616            // we want to start the new one as if the current one is finished,
4617            // but not finish the current one first so that there is no flicker.
4618            // And thus...
4619            final boolean wasFinishing = r.finishing;
4620            r.finishing = true;
4621
4622            // Propagate reply information over to the new activity.
4623            final ActivityRecord resultTo = r.resultTo;
4624            final String resultWho = r.resultWho;
4625            final int requestCode = r.requestCode;
4626            r.resultTo = null;
4627            if (resultTo != null) {
4628                resultTo.removeResultsLocked(r, resultWho, requestCode);
4629            }
4630
4631            final long origId = Binder.clearCallingIdentity();
4632            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4633                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4634                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4635                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4636                    false, false, null, null, null);
4637            Binder.restoreCallingIdentity(origId);
4638
4639            r.finishing = wasFinishing;
4640            if (res != ActivityManager.START_SUCCESS) {
4641                return false;
4642            }
4643            return true;
4644        }
4645    }
4646
4647    @Override
4648    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4649        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4650            String msg = "Permission Denial: startActivityFromRecents called without " +
4651                    START_TASKS_FROM_RECENTS;
4652            Slog.w(TAG, msg);
4653            throw new SecurityException(msg);
4654        }
4655        final long origId = Binder.clearCallingIdentity();
4656        try {
4657            synchronized (this) {
4658                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4659            }
4660        } finally {
4661            Binder.restoreCallingIdentity(origId);
4662        }
4663    }
4664
4665    final int startActivityInPackage(int uid, String callingPackage,
4666            Intent intent, String resolvedType, IBinder resultTo,
4667            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4668            IActivityContainer container, TaskRecord inTask) {
4669
4670        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4671                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4672
4673        // TODO: Switch to user app stacks here.
4674        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4675                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4676                null, null, null, bOptions, false, userId, container, inTask);
4677        return ret;
4678    }
4679
4680    @Override
4681    public final int startActivities(IApplicationThread caller, String callingPackage,
4682            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4683            int userId) {
4684        enforceNotIsolatedCaller("startActivities");
4685        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4686                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4687        // TODO: Switch to user app stacks here.
4688        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4689                resolvedTypes, resultTo, bOptions, userId);
4690        return ret;
4691    }
4692
4693    final int startActivitiesInPackage(int uid, String callingPackage,
4694            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4695            Bundle bOptions, int userId) {
4696
4697        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4698                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4699        // TODO: Switch to user app stacks here.
4700        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4701                resultTo, bOptions, userId);
4702        return ret;
4703    }
4704
4705    @Override
4706    public void reportActivityFullyDrawn(IBinder token) {
4707        synchronized (this) {
4708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4709            if (r == null) {
4710                return;
4711            }
4712            r.reportFullyDrawnLocked();
4713        }
4714    }
4715
4716    @Override
4717    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4718        synchronized (this) {
4719            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4720            if (r == null) {
4721                return;
4722            }
4723            TaskRecord task = r.task;
4724            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4725                // Fixed screen orientation isn't supported when activities aren't in full screen
4726                // mode.
4727                return;
4728            }
4729            final long origId = Binder.clearCallingIdentity();
4730            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4731            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4732                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4733            if (config != null) {
4734                r.frozenBeforeDestroy = true;
4735                if (!updateConfigurationLocked(config, r, false)) {
4736                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4737                }
4738            }
4739            Binder.restoreCallingIdentity(origId);
4740        }
4741    }
4742
4743    @Override
4744    public int getRequestedOrientation(IBinder token) {
4745        synchronized (this) {
4746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4747            if (r == null) {
4748                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4749            }
4750            return mWindowManager.getAppOrientation(r.appToken);
4751        }
4752    }
4753
4754    /**
4755     * This is the internal entry point for handling Activity.finish().
4756     *
4757     * @param token The Binder token referencing the Activity we want to finish.
4758     * @param resultCode Result code, if any, from this Activity.
4759     * @param resultData Result data (Intent), if any, from this Activity.
4760     * @param finishTask Whether to finish the task associated with this Activity.
4761     *
4762     * @return Returns true if the activity successfully finished, or false if it is still running.
4763     */
4764    @Override
4765    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4766            int finishTask) {
4767        // Refuse possible leaked file descriptors
4768        if (resultData != null && resultData.hasFileDescriptors() == true) {
4769            throw new IllegalArgumentException("File descriptors passed in Intent");
4770        }
4771
4772        synchronized(this) {
4773            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4774            if (r == null) {
4775                return true;
4776            }
4777            // Keep track of the root activity of the task before we finish it
4778            TaskRecord tr = r.task;
4779            ActivityRecord rootR = tr.getRootActivity();
4780            if (rootR == null) {
4781                Slog.w(TAG, "Finishing task with all activities already finished");
4782            }
4783            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4784            // finish.
4785            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4786                    mStackSupervisor.isLastLockedTask(tr)) {
4787                Slog.i(TAG, "Not finishing task in lock task mode");
4788                mStackSupervisor.showLockTaskToast();
4789                return false;
4790            }
4791            if (mController != null) {
4792                // Find the first activity that is not finishing.
4793                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4794                if (next != null) {
4795                    // ask watcher if this is allowed
4796                    boolean resumeOK = true;
4797                    try {
4798                        resumeOK = mController.activityResuming(next.packageName);
4799                    } catch (RemoteException e) {
4800                        mController = null;
4801                        Watchdog.getInstance().setActivityController(null);
4802                    }
4803
4804                    if (!resumeOK) {
4805                        Slog.i(TAG, "Not finishing activity because controller resumed");
4806                        return false;
4807                    }
4808                }
4809            }
4810            final long origId = Binder.clearCallingIdentity();
4811            try {
4812                boolean res;
4813                final boolean finishWithRootActivity =
4814                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4815                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4816                        || (finishWithRootActivity && r == rootR)) {
4817                    // If requested, remove the task that is associated to this activity only if it
4818                    // was the root activity in the task. The result code and data is ignored
4819                    // because we don't support returning them across task boundaries. Also, to
4820                    // keep backwards compatibility we remove the task from recents when finishing
4821                    // task with root activity.
4822                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4823                    if (!res) {
4824                        Slog.i(TAG, "Removing task failed to finish activity");
4825                    }
4826                } else {
4827                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4828                            resultData, "app-request", true);
4829                    if (!res) {
4830                        Slog.i(TAG, "Failed to finish by app-request");
4831                    }
4832                }
4833                return res;
4834            } finally {
4835                Binder.restoreCallingIdentity(origId);
4836            }
4837        }
4838    }
4839
4840    @Override
4841    public final void finishHeavyWeightApp() {
4842        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4843                != PackageManager.PERMISSION_GRANTED) {
4844            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4845                    + Binder.getCallingPid()
4846                    + ", uid=" + Binder.getCallingUid()
4847                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4848            Slog.w(TAG, msg);
4849            throw new SecurityException(msg);
4850        }
4851
4852        synchronized(this) {
4853            if (mHeavyWeightProcess == null) {
4854                return;
4855            }
4856
4857            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4858            for (int i = 0; i < activities.size(); i++) {
4859                ActivityRecord r = activities.get(i);
4860                if (!r.finishing && r.isInStackLocked()) {
4861                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4862                            null, "finish-heavy", true);
4863                }
4864            }
4865
4866            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4867                    mHeavyWeightProcess.userId, 0));
4868            mHeavyWeightProcess = null;
4869        }
4870    }
4871
4872    @Override
4873    public void crashApplication(int uid, int initialPid, String packageName,
4874            String message) {
4875        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4876                != PackageManager.PERMISSION_GRANTED) {
4877            String msg = "Permission Denial: crashApplication() from pid="
4878                    + Binder.getCallingPid()
4879                    + ", uid=" + Binder.getCallingUid()
4880                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4881            Slog.w(TAG, msg);
4882            throw new SecurityException(msg);
4883        }
4884
4885        synchronized(this) {
4886            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4887        }
4888    }
4889
4890    @Override
4891    public final void finishSubActivity(IBinder token, String resultWho,
4892            int requestCode) {
4893        synchronized(this) {
4894            final long origId = Binder.clearCallingIdentity();
4895            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4896            if (r != null) {
4897                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4898            }
4899            Binder.restoreCallingIdentity(origId);
4900        }
4901    }
4902
4903    @Override
4904    public boolean finishActivityAffinity(IBinder token) {
4905        synchronized(this) {
4906            final long origId = Binder.clearCallingIdentity();
4907            try {
4908                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4909                if (r == null) {
4910                    return false;
4911                }
4912
4913                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4914                // can finish.
4915                final TaskRecord task = r.task;
4916                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4917                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4918                    mStackSupervisor.showLockTaskToast();
4919                    return false;
4920                }
4921                return task.stack.finishActivityAffinityLocked(r);
4922            } finally {
4923                Binder.restoreCallingIdentity(origId);
4924            }
4925        }
4926    }
4927
4928    @Override
4929    public void finishVoiceTask(IVoiceInteractionSession session) {
4930        synchronized (this) {
4931            final long origId = Binder.clearCallingIdentity();
4932            try {
4933                // TODO: VI Consider treating local voice interactions and voice tasks
4934                // differently here
4935                mStackSupervisor.finishVoiceTask(session);
4936            } finally {
4937                Binder.restoreCallingIdentity(origId);
4938            }
4939        }
4940
4941    }
4942
4943    @Override
4944    public boolean releaseActivityInstance(IBinder token) {
4945        synchronized(this) {
4946            final long origId = Binder.clearCallingIdentity();
4947            try {
4948                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4949                if (r == null) {
4950                    return false;
4951                }
4952                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4953            } finally {
4954                Binder.restoreCallingIdentity(origId);
4955            }
4956        }
4957    }
4958
4959    @Override
4960    public void releaseSomeActivities(IApplicationThread appInt) {
4961        synchronized(this) {
4962            final long origId = Binder.clearCallingIdentity();
4963            try {
4964                ProcessRecord app = getRecordForAppLocked(appInt);
4965                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4966            } finally {
4967                Binder.restoreCallingIdentity(origId);
4968            }
4969        }
4970    }
4971
4972    @Override
4973    public boolean willActivityBeVisible(IBinder token) {
4974        synchronized(this) {
4975            ActivityStack stack = ActivityRecord.getStackLocked(token);
4976            if (stack != null) {
4977                return stack.willActivityBeVisibleLocked(token);
4978            }
4979            return false;
4980        }
4981    }
4982
4983    @Override
4984    public void overridePendingTransition(IBinder token, String packageName,
4985            int enterAnim, int exitAnim) {
4986        synchronized(this) {
4987            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4988            if (self == null) {
4989                return;
4990            }
4991
4992            final long origId = Binder.clearCallingIdentity();
4993
4994            if (self.state == ActivityState.RESUMED
4995                    || self.state == ActivityState.PAUSING) {
4996                mWindowManager.overridePendingAppTransition(packageName,
4997                        enterAnim, exitAnim, null);
4998            }
4999
5000            Binder.restoreCallingIdentity(origId);
5001        }
5002    }
5003
5004    /**
5005     * Main function for removing an existing process from the activity manager
5006     * as a result of that process going away.  Clears out all connections
5007     * to the process.
5008     */
5009    private final void handleAppDiedLocked(ProcessRecord app,
5010            boolean restarting, boolean allowRestart) {
5011        int pid = app.pid;
5012        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5013        if (!kept && !restarting) {
5014            removeLruProcessLocked(app);
5015            if (pid > 0) {
5016                ProcessList.remove(pid);
5017            }
5018        }
5019
5020        if (mProfileProc == app) {
5021            clearProfilerLocked();
5022        }
5023
5024        // Remove this application's activities from active lists.
5025        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5026
5027        app.activities.clear();
5028
5029        if (app.instrumentationClass != null) {
5030            Slog.w(TAG, "Crash of app " + app.processName
5031                  + " running instrumentation " + app.instrumentationClass);
5032            Bundle info = new Bundle();
5033            info.putString("shortMsg", "Process crashed.");
5034            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5035        }
5036
5037        if (!restarting && hasVisibleActivities
5038                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5039            // If there was nothing to resume, and we are not already restarting this process, but
5040            // there is a visible activity that is hosted by the process...  then make sure all
5041            // visible activities are running, taking care of restarting this process.
5042            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5043        }
5044    }
5045
5046    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5047        IBinder threadBinder = thread.asBinder();
5048        // Find the application record.
5049        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5050            ProcessRecord rec = mLruProcesses.get(i);
5051            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5052                return i;
5053            }
5054        }
5055        return -1;
5056    }
5057
5058    final ProcessRecord getRecordForAppLocked(
5059            IApplicationThread thread) {
5060        if (thread == null) {
5061            return null;
5062        }
5063
5064        int appIndex = getLRURecordIndexForAppLocked(thread);
5065        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5066    }
5067
5068    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5069        // If there are no longer any background processes running,
5070        // and the app that died was not running instrumentation,
5071        // then tell everyone we are now low on memory.
5072        boolean haveBg = false;
5073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5074            ProcessRecord rec = mLruProcesses.get(i);
5075            if (rec.thread != null
5076                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5077                haveBg = true;
5078                break;
5079            }
5080        }
5081
5082        if (!haveBg) {
5083            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5084            if (doReport) {
5085                long now = SystemClock.uptimeMillis();
5086                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5087                    doReport = false;
5088                } else {
5089                    mLastMemUsageReportTime = now;
5090                }
5091            }
5092            final ArrayList<ProcessMemInfo> memInfos
5093                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5094            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5095            long now = SystemClock.uptimeMillis();
5096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5097                ProcessRecord rec = mLruProcesses.get(i);
5098                if (rec == dyingProc || rec.thread == null) {
5099                    continue;
5100                }
5101                if (doReport) {
5102                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5103                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5104                }
5105                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5106                    // The low memory report is overriding any current
5107                    // state for a GC request.  Make sure to do
5108                    // heavy/important/visible/foreground processes first.
5109                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5110                        rec.lastRequestedGc = 0;
5111                    } else {
5112                        rec.lastRequestedGc = rec.lastLowMemory;
5113                    }
5114                    rec.reportLowMemory = true;
5115                    rec.lastLowMemory = now;
5116                    mProcessesToGc.remove(rec);
5117                    addProcessToGcListLocked(rec);
5118                }
5119            }
5120            if (doReport) {
5121                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5122                mHandler.sendMessage(msg);
5123            }
5124            scheduleAppGcsLocked();
5125        }
5126    }
5127
5128    final void appDiedLocked(ProcessRecord app) {
5129       appDiedLocked(app, app.pid, app.thread, false);
5130    }
5131
5132    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5133            boolean fromBinderDied) {
5134        // First check if this ProcessRecord is actually active for the pid.
5135        synchronized (mPidsSelfLocked) {
5136            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5137            if (curProc != app) {
5138                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5139                return;
5140            }
5141        }
5142
5143        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5144        synchronized (stats) {
5145            stats.noteProcessDiedLocked(app.info.uid, pid);
5146        }
5147
5148        if (!app.killed) {
5149            if (!fromBinderDied) {
5150                Process.killProcessQuiet(pid);
5151            }
5152            killProcessGroup(app.uid, pid);
5153            app.killed = true;
5154        }
5155
5156        // Clean up already done if the process has been re-started.
5157        if (app.pid == pid && app.thread != null &&
5158                app.thread.asBinder() == thread.asBinder()) {
5159            boolean doLowMem = app.instrumentationClass == null;
5160            boolean doOomAdj = doLowMem;
5161            if (!app.killedByAm) {
5162                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5163                        + ") has died");
5164                mAllowLowerMemLevel = true;
5165            } else {
5166                // Note that we always want to do oom adj to update our state with the
5167                // new number of procs.
5168                mAllowLowerMemLevel = false;
5169                doLowMem = false;
5170            }
5171            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5172            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5173                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5174            handleAppDiedLocked(app, false, true);
5175
5176            if (doOomAdj) {
5177                updateOomAdjLocked();
5178            }
5179            if (doLowMem) {
5180                doLowMemReportIfNeededLocked(app);
5181            }
5182        } else if (app.pid != pid) {
5183            // A new process has already been started.
5184            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5185                    + ") has died and restarted (pid " + app.pid + ").");
5186            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5187        } else if (DEBUG_PROCESSES) {
5188            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5189                    + thread.asBinder());
5190        }
5191    }
5192
5193    /**
5194     * If a stack trace dump file is configured, dump process stack traces.
5195     * @param clearTraces causes the dump file to be erased prior to the new
5196     *    traces being written, if true; when false, the new traces will be
5197     *    appended to any existing file content.
5198     * @param firstPids of dalvik VM processes to dump stack traces for first
5199     * @param lastPids of dalvik VM processes to dump stack traces for last
5200     * @param nativeProcs optional list of native process names to dump stack crawls
5201     * @return file containing stack traces, or null if no dump file is configured
5202     */
5203    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5204            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5205        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5206        if (tracesPath == null || tracesPath.length() == 0) {
5207            return null;
5208        }
5209
5210        File tracesFile = new File(tracesPath);
5211        try {
5212            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5213            tracesFile.createNewFile();
5214            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5215        } catch (IOException e) {
5216            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5217            return null;
5218        }
5219
5220        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5221        return tracesFile;
5222    }
5223
5224    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5225            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5226        // Use a FileObserver to detect when traces finish writing.
5227        // The order of traces is considered important to maintain for legibility.
5228        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5229            @Override
5230            public synchronized void onEvent(int event, String path) { notify(); }
5231        };
5232
5233        try {
5234            observer.startWatching();
5235
5236            // First collect all of the stacks of the most important pids.
5237            if (firstPids != null) {
5238                try {
5239                    int num = firstPids.size();
5240                    for (int i = 0; i < num; i++) {
5241                        synchronized (observer) {
5242                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5243                                    + firstPids.get(i));
5244                            final long sime = SystemClock.elapsedRealtime();
5245                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5246                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5247                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5248                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5249                        }
5250                    }
5251                } catch (InterruptedException e) {
5252                    Slog.wtf(TAG, e);
5253                }
5254            }
5255
5256            // Next collect the stacks of the native pids
5257            if (nativeProcs != null) {
5258                int[] pids = Process.getPidsForCommands(nativeProcs);
5259                if (pids != null) {
5260                    for (int pid : pids) {
5261                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5262                        final long sime = SystemClock.elapsedRealtime();
5263                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5264                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5265                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5266                    }
5267                }
5268            }
5269
5270            // Lastly, measure CPU usage.
5271            if (processCpuTracker != null) {
5272                processCpuTracker.init();
5273                System.gc();
5274                processCpuTracker.update();
5275                try {
5276                    synchronized (processCpuTracker) {
5277                        processCpuTracker.wait(500); // measure over 1/2 second.
5278                    }
5279                } catch (InterruptedException e) {
5280                }
5281                processCpuTracker.update();
5282
5283                // We'll take the stack crawls of just the top apps using CPU.
5284                final int N = processCpuTracker.countWorkingStats();
5285                int numProcs = 0;
5286                for (int i=0; i<N && numProcs<5; i++) {
5287                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5288                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5289                        numProcs++;
5290                        try {
5291                            synchronized (observer) {
5292                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5293                                        + stats.pid);
5294                                final long stime = SystemClock.elapsedRealtime();
5295                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5296                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5297                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5298                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5299                            }
5300                        } catch (InterruptedException e) {
5301                            Slog.wtf(TAG, e);
5302                        }
5303                    } else if (DEBUG_ANR) {
5304                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5305                                + stats.pid);
5306                    }
5307                }
5308            }
5309        } finally {
5310            observer.stopWatching();
5311        }
5312    }
5313
5314    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5315        if (true || IS_USER_BUILD) {
5316            return;
5317        }
5318        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5319        if (tracesPath == null || tracesPath.length() == 0) {
5320            return;
5321        }
5322
5323        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5324        StrictMode.allowThreadDiskWrites();
5325        try {
5326            final File tracesFile = new File(tracesPath);
5327            final File tracesDir = tracesFile.getParentFile();
5328            final File tracesTmp = new File(tracesDir, "__tmp__");
5329            try {
5330                if (tracesFile.exists()) {
5331                    tracesTmp.delete();
5332                    tracesFile.renameTo(tracesTmp);
5333                }
5334                StringBuilder sb = new StringBuilder();
5335                Time tobj = new Time();
5336                tobj.set(System.currentTimeMillis());
5337                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5338                sb.append(": ");
5339                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5340                sb.append(" since ");
5341                sb.append(msg);
5342                FileOutputStream fos = new FileOutputStream(tracesFile);
5343                fos.write(sb.toString().getBytes());
5344                if (app == null) {
5345                    fos.write("\n*** No application process!".getBytes());
5346                }
5347                fos.close();
5348                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5349            } catch (IOException e) {
5350                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5351                return;
5352            }
5353
5354            if (app != null) {
5355                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5356                firstPids.add(app.pid);
5357                dumpStackTraces(tracesPath, firstPids, null, null, null);
5358            }
5359
5360            File lastTracesFile = null;
5361            File curTracesFile = null;
5362            for (int i=9; i>=0; i--) {
5363                String name = String.format(Locale.US, "slow%02d.txt", i);
5364                curTracesFile = new File(tracesDir, name);
5365                if (curTracesFile.exists()) {
5366                    if (lastTracesFile != null) {
5367                        curTracesFile.renameTo(lastTracesFile);
5368                    } else {
5369                        curTracesFile.delete();
5370                    }
5371                }
5372                lastTracesFile = curTracesFile;
5373            }
5374            tracesFile.renameTo(curTracesFile);
5375            if (tracesTmp.exists()) {
5376                tracesTmp.renameTo(tracesFile);
5377            }
5378        } finally {
5379            StrictMode.setThreadPolicy(oldPolicy);
5380        }
5381    }
5382
5383    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5384        if (!mLaunchWarningShown) {
5385            mLaunchWarningShown = true;
5386            mUiHandler.post(new Runnable() {
5387                @Override
5388                public void run() {
5389                    synchronized (ActivityManagerService.this) {
5390                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5391                        d.show();
5392                        mUiHandler.postDelayed(new Runnable() {
5393                            @Override
5394                            public void run() {
5395                                synchronized (ActivityManagerService.this) {
5396                                    d.dismiss();
5397                                    mLaunchWarningShown = false;
5398                                }
5399                            }
5400                        }, 4000);
5401                    }
5402                }
5403            });
5404        }
5405    }
5406
5407    @Override
5408    public boolean clearApplicationUserData(final String packageName,
5409            final IPackageDataObserver observer, int userId) {
5410        enforceNotIsolatedCaller("clearApplicationUserData");
5411        int uid = Binder.getCallingUid();
5412        int pid = Binder.getCallingPid();
5413        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5414                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5415
5416
5417        long callingId = Binder.clearCallingIdentity();
5418        try {
5419            IPackageManager pm = AppGlobals.getPackageManager();
5420            int pkgUid = -1;
5421            synchronized(this) {
5422                if (getPackageManagerInternalLocked().canPackageBeWiped(
5423                        userId, packageName)) {
5424                    throw new SecurityException(
5425                            "Cannot clear data for a device owner or a profile owner");
5426                }
5427
5428                try {
5429                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5430                } catch (RemoteException e) {
5431                }
5432                if (pkgUid == -1) {
5433                    Slog.w(TAG, "Invalid packageName: " + packageName);
5434                    if (observer != null) {
5435                        try {
5436                            observer.onRemoveCompleted(packageName, false);
5437                        } catch (RemoteException e) {
5438                            Slog.i(TAG, "Observer no longer exists.");
5439                        }
5440                    }
5441                    return false;
5442                }
5443                if (uid == pkgUid || checkComponentPermission(
5444                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5445                        pid, uid, -1, true)
5446                        == PackageManager.PERMISSION_GRANTED) {
5447                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5448                } else {
5449                    throw new SecurityException("PID " + pid + " does not have permission "
5450                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5451                                    + " of package " + packageName);
5452                }
5453
5454                // Remove all tasks match the cleared application package and user
5455                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5456                    final TaskRecord tr = mRecentTasks.get(i);
5457                    final String taskPackageName =
5458                            tr.getBaseIntent().getComponent().getPackageName();
5459                    if (tr.userId != userId) continue;
5460                    if (!taskPackageName.equals(packageName)) continue;
5461                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5462                }
5463            }
5464
5465            final int pkgUidF = pkgUid;
5466            final int userIdF = userId;
5467            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5468                @Override
5469                public void onRemoveCompleted(String packageName, boolean succeeded)
5470                        throws RemoteException {
5471                    synchronized (ActivityManagerService.this) {
5472                        finishForceStopPackageLocked(packageName, pkgUidF);
5473                    }
5474
5475                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5476                            Uri.fromParts("package", packageName, null));
5477                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5478                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5479                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5480                            null, null, 0, null, null, null, null, false, false, userIdF);
5481
5482                    if (observer != null) {
5483                        observer.onRemoveCompleted(packageName, succeeded);
5484                    }
5485                }
5486            };
5487
5488            try {
5489                // Clear application user data
5490                pm.clearApplicationUserData(packageName, localObserver, userId);
5491
5492                synchronized(this) {
5493                    // Remove all permissions granted from/to this package
5494                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5495                }
5496
5497                // Remove all zen rules created by this package; revoke it's zen access.
5498                INotificationManager inm = NotificationManager.getService();
5499                inm.removeAutomaticZenRules(packageName);
5500                inm.setNotificationPolicyAccessGranted(packageName, false);
5501
5502            } catch (RemoteException e) {
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507        return true;
5508    }
5509
5510    @Override
5511    public void killBackgroundProcesses(final String packageName, int userId) {
5512        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5513                != PackageManager.PERMISSION_GRANTED &&
5514                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5515                        != PackageManager.PERMISSION_GRANTED) {
5516            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5517                    + Binder.getCallingPid()
5518                    + ", uid=" + Binder.getCallingUid()
5519                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5520            Slog.w(TAG, msg);
5521            throw new SecurityException(msg);
5522        }
5523
5524        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5525                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5526        long callingId = Binder.clearCallingIdentity();
5527        try {
5528            IPackageManager pm = AppGlobals.getPackageManager();
5529            synchronized(this) {
5530                int appId = -1;
5531                try {
5532                    appId = UserHandle.getAppId(
5533                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5534                } catch (RemoteException e) {
5535                }
5536                if (appId == -1) {
5537                    Slog.w(TAG, "Invalid packageName: " + packageName);
5538                    return;
5539                }
5540                killPackageProcessesLocked(packageName, appId, userId,
5541                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5542            }
5543        } finally {
5544            Binder.restoreCallingIdentity(callingId);
5545        }
5546    }
5547
5548    @Override
5549    public void killAllBackgroundProcesses() {
5550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5551                != PackageManager.PERMISSION_GRANTED) {
5552            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5553                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5554                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5555            Slog.w(TAG, msg);
5556            throw new SecurityException(msg);
5557        }
5558
5559        final long callingId = Binder.clearCallingIdentity();
5560        try {
5561            synchronized (this) {
5562                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5563                final int NP = mProcessNames.getMap().size();
5564                for (int ip = 0; ip < NP; ip++) {
5565                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5566                    final int NA = apps.size();
5567                    for (int ia = 0; ia < NA; ia++) {
5568                        final ProcessRecord app = apps.valueAt(ia);
5569                        if (app.persistent) {
5570                            // We don't kill persistent processes.
5571                            continue;
5572                        }
5573                        if (app.removed) {
5574                            procs.add(app);
5575                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5576                            app.removed = true;
5577                            procs.add(app);
5578                        }
5579                    }
5580                }
5581
5582                final int N = procs.size();
5583                for (int i = 0; i < N; i++) {
5584                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5585                }
5586
5587                mAllowLowerMemLevel = true;
5588
5589                updateOomAdjLocked();
5590                doLowMemReportIfNeededLocked(null);
5591            }
5592        } finally {
5593            Binder.restoreCallingIdentity(callingId);
5594        }
5595    }
5596
5597    /**
5598     * Kills all background processes, except those matching any of the
5599     * specified properties.
5600     *
5601     * @param minTargetSdk the target SDK version at or above which to preserve
5602     *                     processes, or {@code -1} to ignore the target SDK
5603     * @param maxProcState the process state at or below which to preserve
5604     *                     processes, or {@code -1} to ignore the process state
5605     */
5606    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5607        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5608                != PackageManager.PERMISSION_GRANTED) {
5609            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5610                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5611                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5612            Slog.w(TAG, msg);
5613            throw new SecurityException(msg);
5614        }
5615
5616        final long callingId = Binder.clearCallingIdentity();
5617        try {
5618            synchronized (this) {
5619                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5620                final int NP = mProcessNames.getMap().size();
5621                for (int ip = 0; ip < NP; ip++) {
5622                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5623                    final int NA = apps.size();
5624                    for (int ia = 0; ia < NA; ia++) {
5625                        final ProcessRecord app = apps.valueAt(ia);
5626                        if (app.removed) {
5627                            procs.add(app);
5628                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5629                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5630                            app.removed = true;
5631                            procs.add(app);
5632                        }
5633                    }
5634                }
5635
5636                final int N = procs.size();
5637                for (int i = 0; i < N; i++) {
5638                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5639                }
5640            }
5641        } finally {
5642            Binder.restoreCallingIdentity(callingId);
5643        }
5644    }
5645
5646    @Override
5647    public void forceStopPackage(final String packageName, int userId) {
5648        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5649                != PackageManager.PERMISSION_GRANTED) {
5650            String msg = "Permission Denial: forceStopPackage() from pid="
5651                    + Binder.getCallingPid()
5652                    + ", uid=" + Binder.getCallingUid()
5653                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5654            Slog.w(TAG, msg);
5655            throw new SecurityException(msg);
5656        }
5657        final int callingPid = Binder.getCallingPid();
5658        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5659                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5660        long callingId = Binder.clearCallingIdentity();
5661        try {
5662            IPackageManager pm = AppGlobals.getPackageManager();
5663            synchronized(this) {
5664                int[] users = userId == UserHandle.USER_ALL
5665                        ? mUserController.getUsers() : new int[] { userId };
5666                for (int user : users) {
5667                    int pkgUid = -1;
5668                    try {
5669                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5670                                user);
5671                    } catch (RemoteException e) {
5672                    }
5673                    if (pkgUid == -1) {
5674                        Slog.w(TAG, "Invalid packageName: " + packageName);
5675                        continue;
5676                    }
5677                    try {
5678                        pm.setPackageStoppedState(packageName, true, user);
5679                    } catch (RemoteException e) {
5680                    } catch (IllegalArgumentException e) {
5681                        Slog.w(TAG, "Failed trying to unstop package "
5682                                + packageName + ": " + e);
5683                    }
5684                    if (mUserController.isUserRunningLocked(user, 0)) {
5685                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5686                        finishForceStopPackageLocked(packageName, pkgUid);
5687                    }
5688                }
5689            }
5690        } finally {
5691            Binder.restoreCallingIdentity(callingId);
5692        }
5693    }
5694
5695    @Override
5696    public void addPackageDependency(String packageName) {
5697        synchronized (this) {
5698            int callingPid = Binder.getCallingPid();
5699            if (callingPid == Process.myPid()) {
5700                //  Yeah, um, no.
5701                return;
5702            }
5703            ProcessRecord proc;
5704            synchronized (mPidsSelfLocked) {
5705                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5706            }
5707            if (proc != null) {
5708                if (proc.pkgDeps == null) {
5709                    proc.pkgDeps = new ArraySet<String>(1);
5710                }
5711                proc.pkgDeps.add(packageName);
5712            }
5713        }
5714    }
5715
5716    /*
5717     * The pkg name and app id have to be specified.
5718     */
5719    @Override
5720    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5721        if (pkg == null) {
5722            return;
5723        }
5724        // Make sure the uid is valid.
5725        if (appid < 0) {
5726            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5727            return;
5728        }
5729        int callerUid = Binder.getCallingUid();
5730        // Only the system server can kill an application
5731        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5732            // Post an aysnc message to kill the application
5733            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5734            msg.arg1 = appid;
5735            msg.arg2 = 0;
5736            Bundle bundle = new Bundle();
5737            bundle.putString("pkg", pkg);
5738            bundle.putString("reason", reason);
5739            msg.obj = bundle;
5740            mHandler.sendMessage(msg);
5741        } else {
5742            throw new SecurityException(callerUid + " cannot kill pkg: " +
5743                    pkg);
5744        }
5745    }
5746
5747    @Override
5748    public void closeSystemDialogs(String reason) {
5749        enforceNotIsolatedCaller("closeSystemDialogs");
5750
5751        final int pid = Binder.getCallingPid();
5752        final int uid = Binder.getCallingUid();
5753        final long origId = Binder.clearCallingIdentity();
5754        try {
5755            synchronized (this) {
5756                // Only allow this from foreground processes, so that background
5757                // applications can't abuse it to prevent system UI from being shown.
5758                if (uid >= Process.FIRST_APPLICATION_UID) {
5759                    ProcessRecord proc;
5760                    synchronized (mPidsSelfLocked) {
5761                        proc = mPidsSelfLocked.get(pid);
5762                    }
5763                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5764                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5765                                + " from background process " + proc);
5766                        return;
5767                    }
5768                }
5769                closeSystemDialogsLocked(reason);
5770            }
5771        } finally {
5772            Binder.restoreCallingIdentity(origId);
5773        }
5774    }
5775
5776    void closeSystemDialogsLocked(String reason) {
5777        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5778        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5779                | Intent.FLAG_RECEIVER_FOREGROUND);
5780        if (reason != null) {
5781            intent.putExtra("reason", reason);
5782        }
5783        mWindowManager.closeSystemDialogs(reason);
5784
5785        mStackSupervisor.closeSystemDialogsLocked();
5786
5787        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5788                AppOpsManager.OP_NONE, null, false, false,
5789                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5790    }
5791
5792    @Override
5793    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5794        enforceNotIsolatedCaller("getProcessMemoryInfo");
5795        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5796        for (int i=pids.length-1; i>=0; i--) {
5797            ProcessRecord proc;
5798            int oomAdj;
5799            synchronized (this) {
5800                synchronized (mPidsSelfLocked) {
5801                    proc = mPidsSelfLocked.get(pids[i]);
5802                    oomAdj = proc != null ? proc.setAdj : 0;
5803                }
5804            }
5805            infos[i] = new Debug.MemoryInfo();
5806            Debug.getMemoryInfo(pids[i], infos[i]);
5807            if (proc != null) {
5808                synchronized (this) {
5809                    if (proc.thread != null && proc.setAdj == oomAdj) {
5810                        // Record this for posterity if the process has been stable.
5811                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5812                                infos[i].getTotalUss(), false, proc.pkgList);
5813                    }
5814                }
5815            }
5816        }
5817        return infos;
5818    }
5819
5820    @Override
5821    public long[] getProcessPss(int[] pids) {
5822        enforceNotIsolatedCaller("getProcessPss");
5823        long[] pss = new long[pids.length];
5824        for (int i=pids.length-1; i>=0; i--) {
5825            ProcessRecord proc;
5826            int oomAdj;
5827            synchronized (this) {
5828                synchronized (mPidsSelfLocked) {
5829                    proc = mPidsSelfLocked.get(pids[i]);
5830                    oomAdj = proc != null ? proc.setAdj : 0;
5831                }
5832            }
5833            long[] tmpUss = new long[1];
5834            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5835            if (proc != null) {
5836                synchronized (this) {
5837                    if (proc.thread != null && proc.setAdj == oomAdj) {
5838                        // Record this for posterity if the process has been stable.
5839                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5840                    }
5841                }
5842            }
5843        }
5844        return pss;
5845    }
5846
5847    @Override
5848    public void killApplicationProcess(String processName, int uid) {
5849        if (processName == null) {
5850            return;
5851        }
5852
5853        int callerUid = Binder.getCallingUid();
5854        // Only the system server can kill an application
5855        if (callerUid == Process.SYSTEM_UID) {
5856            synchronized (this) {
5857                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5858                if (app != null && app.thread != null) {
5859                    try {
5860                        app.thread.scheduleSuicide();
5861                    } catch (RemoteException e) {
5862                        // If the other end already died, then our work here is done.
5863                    }
5864                } else {
5865                    Slog.w(TAG, "Process/uid not found attempting kill of "
5866                            + processName + " / " + uid);
5867                }
5868            }
5869        } else {
5870            throw new SecurityException(callerUid + " cannot kill app process: " +
5871                    processName);
5872        }
5873    }
5874
5875    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5876        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5877                false, true, false, false, UserHandle.getUserId(uid), reason);
5878    }
5879
5880    private void finishForceStopPackageLocked(final String packageName, int uid) {
5881        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5882                Uri.fromParts("package", packageName, null));
5883        if (!mProcessesReady) {
5884            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5885                    | Intent.FLAG_RECEIVER_FOREGROUND);
5886        }
5887        intent.putExtra(Intent.EXTRA_UID, uid);
5888        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5889        broadcastIntentLocked(null, null, intent,
5890                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5891                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5892    }
5893
5894
5895    private final boolean killPackageProcessesLocked(String packageName, int appId,
5896            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5897            boolean doit, boolean evenPersistent, String reason) {
5898        ArrayList<ProcessRecord> procs = new ArrayList<>();
5899
5900        // Remove all processes this package may have touched: all with the
5901        // same UID (except for the system or root user), and all whose name
5902        // matches the package name.
5903        final int NP = mProcessNames.getMap().size();
5904        for (int ip=0; ip<NP; ip++) {
5905            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5906            final int NA = apps.size();
5907            for (int ia=0; ia<NA; ia++) {
5908                ProcessRecord app = apps.valueAt(ia);
5909                if (app.persistent && !evenPersistent) {
5910                    // we don't kill persistent processes
5911                    continue;
5912                }
5913                if (app.removed) {
5914                    if (doit) {
5915                        procs.add(app);
5916                    }
5917                    continue;
5918                }
5919
5920                // Skip process if it doesn't meet our oom adj requirement.
5921                if (app.setAdj < minOomAdj) {
5922                    continue;
5923                }
5924
5925                // If no package is specified, we call all processes under the
5926                // give user id.
5927                if (packageName == null) {
5928                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5929                        continue;
5930                    }
5931                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5932                        continue;
5933                    }
5934                // Package has been specified, we want to hit all processes
5935                // that match it.  We need to qualify this by the processes
5936                // that are running under the specified app and user ID.
5937                } else {
5938                    final boolean isDep = app.pkgDeps != null
5939                            && app.pkgDeps.contains(packageName);
5940                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5941                        continue;
5942                    }
5943                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5944                        continue;
5945                    }
5946                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5947                        continue;
5948                    }
5949                }
5950
5951                // Process has passed all conditions, kill it!
5952                if (!doit) {
5953                    return true;
5954                }
5955                app.removed = true;
5956                procs.add(app);
5957            }
5958        }
5959
5960        int N = procs.size();
5961        for (int i=0; i<N; i++) {
5962            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5963        }
5964        updateOomAdjLocked();
5965        return N > 0;
5966    }
5967
5968    private void cleanupDisabledPackageComponentsLocked(
5969            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5970
5971        Set<String> disabledClasses = null;
5972        boolean packageDisabled = false;
5973        IPackageManager pm = AppGlobals.getPackageManager();
5974
5975        if (changedClasses == null) {
5976            // Nothing changed...
5977            return;
5978        }
5979
5980        // Determine enable/disable state of the package and its components.
5981        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5982        for (int i = changedClasses.length - 1; i >= 0; i--) {
5983            final String changedClass = changedClasses[i];
5984
5985            if (changedClass.equals(packageName)) {
5986                try {
5987                    // Entire package setting changed
5988                    enabled = pm.getApplicationEnabledSetting(packageName,
5989                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5990                } catch (Exception e) {
5991                    // No such package/component; probably racing with uninstall.  In any
5992                    // event it means we have nothing further to do here.
5993                    return;
5994                }
5995                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5996                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5997                if (packageDisabled) {
5998                    // Entire package is disabled.
5999                    // No need to continue to check component states.
6000                    disabledClasses = null;
6001                    break;
6002                }
6003            } else {
6004                try {
6005                    enabled = pm.getComponentEnabledSetting(
6006                            new ComponentName(packageName, changedClass),
6007                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6008                } catch (Exception e) {
6009                    // As above, probably racing with uninstall.
6010                    return;
6011                }
6012                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6013                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6014                    if (disabledClasses == null) {
6015                        disabledClasses = new ArraySet<>(changedClasses.length);
6016                    }
6017                    disabledClasses.add(changedClass);
6018                }
6019            }
6020        }
6021
6022        if (!packageDisabled && disabledClasses == null) {
6023            // Nothing to do here...
6024            return;
6025        }
6026
6027        // Clean-up disabled activities.
6028        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6029                packageName, disabledClasses, true, false, userId) && mBooted) {
6030            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6031            mStackSupervisor.scheduleIdleLocked();
6032        }
6033
6034        // Clean-up disabled tasks
6035        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6036
6037        // Clean-up disabled services.
6038        mServices.bringDownDisabledPackageServicesLocked(
6039                packageName, disabledClasses, userId, false, killProcess, true);
6040
6041        // Clean-up disabled providers.
6042        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6043        mProviderMap.collectPackageProvidersLocked(
6044                packageName, disabledClasses, true, false, userId, providers);
6045        for (int i = providers.size() - 1; i >= 0; i--) {
6046            removeDyingProviderLocked(null, providers.get(i), true);
6047        }
6048
6049        // Clean-up disabled broadcast receivers.
6050        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6051            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6052                    packageName, disabledClasses, userId, true);
6053        }
6054
6055    }
6056
6057    final boolean clearBroadcastQueueForUserLocked(int userId) {
6058        boolean didSomething = false;
6059        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6060            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6061                    null, null, userId, true);
6062        }
6063        return didSomething;
6064    }
6065
6066    final boolean forceStopPackageLocked(String packageName, int appId,
6067            boolean callerWillRestart, boolean purgeCache, boolean doit,
6068            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6069        int i;
6070
6071        if (userId == UserHandle.USER_ALL && packageName == null) {
6072            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6073        }
6074
6075        if (appId < 0 && packageName != null) {
6076            try {
6077                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6078                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6079            } catch (RemoteException e) {
6080            }
6081        }
6082
6083        if (doit) {
6084            if (packageName != null) {
6085                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6086                        + " user=" + userId + ": " + reason);
6087            } else {
6088                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6089            }
6090
6091            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6092        }
6093
6094        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6095                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6096                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6097
6098        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6099                packageName, null, doit, evenPersistent, userId)) {
6100            if (!doit) {
6101                return true;
6102            }
6103            didSomething = true;
6104        }
6105
6106        if (mServices.bringDownDisabledPackageServicesLocked(
6107                packageName, null, userId, evenPersistent, true, doit)) {
6108            if (!doit) {
6109                return true;
6110            }
6111            didSomething = true;
6112        }
6113
6114        if (packageName == null) {
6115            // Remove all sticky broadcasts from this user.
6116            mStickyBroadcasts.remove(userId);
6117        }
6118
6119        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6120        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6121                userId, providers)) {
6122            if (!doit) {
6123                return true;
6124            }
6125            didSomething = true;
6126        }
6127        for (i = providers.size() - 1; i >= 0; i--) {
6128            removeDyingProviderLocked(null, providers.get(i), true);
6129        }
6130
6131        // Remove transient permissions granted from/to this package/user
6132        removeUriPermissionsForPackageLocked(packageName, userId, false);
6133
6134        if (doit) {
6135            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137                        packageName, null, userId, doit);
6138            }
6139        }
6140
6141        if (packageName == null || uninstalling) {
6142            // Remove pending intents.  For now we only do this when force
6143            // stopping users, because we have some problems when doing this
6144            // for packages -- app widgets are not currently cleaned up for
6145            // such packages, so they can be left with bad pending intents.
6146            if (mIntentSenderRecords.size() > 0) {
6147                Iterator<WeakReference<PendingIntentRecord>> it
6148                        = mIntentSenderRecords.values().iterator();
6149                while (it.hasNext()) {
6150                    WeakReference<PendingIntentRecord> wpir = it.next();
6151                    if (wpir == null) {
6152                        it.remove();
6153                        continue;
6154                    }
6155                    PendingIntentRecord pir = wpir.get();
6156                    if (pir == null) {
6157                        it.remove();
6158                        continue;
6159                    }
6160                    if (packageName == null) {
6161                        // Stopping user, remove all objects for the user.
6162                        if (pir.key.userId != userId) {
6163                            // Not the same user, skip it.
6164                            continue;
6165                        }
6166                    } else {
6167                        if (UserHandle.getAppId(pir.uid) != appId) {
6168                            // Different app id, skip it.
6169                            continue;
6170                        }
6171                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6172                            // Different user, skip it.
6173                            continue;
6174                        }
6175                        if (!pir.key.packageName.equals(packageName)) {
6176                            // Different package, skip it.
6177                            continue;
6178                        }
6179                    }
6180                    if (!doit) {
6181                        return true;
6182                    }
6183                    didSomething = true;
6184                    it.remove();
6185                    pir.canceled = true;
6186                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6187                        pir.key.activity.pendingResults.remove(pir.ref);
6188                    }
6189                }
6190            }
6191        }
6192
6193        if (doit) {
6194            if (purgeCache && packageName != null) {
6195                AttributeCache ac = AttributeCache.instance();
6196                if (ac != null) {
6197                    ac.removePackage(packageName);
6198                }
6199            }
6200            if (mBooted) {
6201                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6202                mStackSupervisor.scheduleIdleLocked();
6203            }
6204        }
6205
6206        return didSomething;
6207    }
6208
6209    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6210        ProcessRecord old = mProcessNames.remove(name, uid);
6211        if (old != null) {
6212            old.uidRecord.numProcs--;
6213            if (old.uidRecord.numProcs == 0) {
6214                // No more processes using this uid, tell clients it is gone.
6215                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6216                        "No more processes in " + old.uidRecord);
6217                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6218                mActiveUids.remove(uid);
6219                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6220            }
6221            old.uidRecord = null;
6222        }
6223        mIsolatedProcesses.remove(uid);
6224        return old;
6225    }
6226
6227    private final void addProcessNameLocked(ProcessRecord proc) {
6228        // We shouldn't already have a process under this name, but just in case we
6229        // need to clean up whatever may be there now.
6230        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6231        if (old == proc && proc.persistent) {
6232            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6233            Slog.w(TAG, "Re-adding persistent process " + proc);
6234        } else if (old != null) {
6235            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6236        }
6237        UidRecord uidRec = mActiveUids.get(proc.uid);
6238        if (uidRec == null) {
6239            uidRec = new UidRecord(proc.uid);
6240            // This is the first appearance of the uid, report it now!
6241            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6242                    "Creating new process uid: " + uidRec);
6243            mActiveUids.put(proc.uid, uidRec);
6244            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6245            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6246        }
6247        proc.uidRecord = uidRec;
6248        uidRec.numProcs++;
6249        mProcessNames.put(proc.processName, proc.uid, proc);
6250        if (proc.isolated) {
6251            mIsolatedProcesses.put(proc.uid, proc);
6252        }
6253    }
6254
6255    boolean removeProcessLocked(ProcessRecord app,
6256            boolean callerWillRestart, boolean allowRestart, String reason) {
6257        final String name = app.processName;
6258        final int uid = app.uid;
6259        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6260            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6261
6262        ProcessRecord old = mProcessNames.get(name, uid);
6263        if (old != app) {
6264            // This process is no longer active, so nothing to do.
6265            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6266            return false;
6267        }
6268        removeProcessNameLocked(name, uid);
6269        if (mHeavyWeightProcess == app) {
6270            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6271                    mHeavyWeightProcess.userId, 0));
6272            mHeavyWeightProcess = null;
6273        }
6274        boolean needRestart = false;
6275        if (app.pid > 0 && app.pid != MY_PID) {
6276            int pid = app.pid;
6277            synchronized (mPidsSelfLocked) {
6278                mPidsSelfLocked.remove(pid);
6279                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6280            }
6281            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6282            if (app.isolated) {
6283                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6284            }
6285            boolean willRestart = false;
6286            if (app.persistent && !app.isolated) {
6287                if (!callerWillRestart) {
6288                    willRestart = true;
6289                } else {
6290                    needRestart = true;
6291                }
6292            }
6293            app.kill(reason, true);
6294            handleAppDiedLocked(app, willRestart, allowRestart);
6295            if (willRestart) {
6296                removeLruProcessLocked(app);
6297                addAppLocked(app.info, false, null /* ABI override */);
6298            }
6299        } else {
6300            mRemovedProcesses.add(app);
6301        }
6302
6303        return needRestart;
6304    }
6305
6306    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6307        cleanupAppInLaunchingProvidersLocked(app, true);
6308        removeProcessLocked(app, false, true, "timeout publishing content providers");
6309    }
6310
6311    private final void processStartTimedOutLocked(ProcessRecord app) {
6312        final int pid = app.pid;
6313        boolean gone = false;
6314        synchronized (mPidsSelfLocked) {
6315            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6316            if (knownApp != null && knownApp.thread == null) {
6317                mPidsSelfLocked.remove(pid);
6318                gone = true;
6319            }
6320        }
6321
6322        if (gone) {
6323            Slog.w(TAG, "Process " + app + " failed to attach");
6324            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6325                    pid, app.uid, app.processName);
6326            removeProcessNameLocked(app.processName, app.uid);
6327            if (mHeavyWeightProcess == app) {
6328                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6329                        mHeavyWeightProcess.userId, 0));
6330                mHeavyWeightProcess = null;
6331            }
6332            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6333            if (app.isolated) {
6334                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6335            }
6336            // Take care of any launching providers waiting for this process.
6337            cleanupAppInLaunchingProvidersLocked(app, true);
6338            // Take care of any services that are waiting for the process.
6339            mServices.processStartTimedOutLocked(app);
6340            app.kill("start timeout", true);
6341            removeLruProcessLocked(app);
6342            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6343                Slog.w(TAG, "Unattached app died before backup, skipping");
6344                try {
6345                    IBackupManager bm = IBackupManager.Stub.asInterface(
6346                            ServiceManager.getService(Context.BACKUP_SERVICE));
6347                    bm.agentDisconnected(app.info.packageName);
6348                } catch (RemoteException e) {
6349                    // Can't happen; the backup manager is local
6350                }
6351            }
6352            if (isPendingBroadcastProcessLocked(pid)) {
6353                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6354                skipPendingBroadcastLocked(pid);
6355            }
6356        } else {
6357            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6358        }
6359    }
6360
6361    private final boolean attachApplicationLocked(IApplicationThread thread,
6362            int pid) {
6363
6364        // Find the application record that is being attached...  either via
6365        // the pid if we are running in multiple processes, or just pull the
6366        // next app record if we are emulating process with anonymous threads.
6367        ProcessRecord app;
6368        if (pid != MY_PID && pid >= 0) {
6369            synchronized (mPidsSelfLocked) {
6370                app = mPidsSelfLocked.get(pid);
6371            }
6372        } else {
6373            app = null;
6374        }
6375
6376        if (app == null) {
6377            Slog.w(TAG, "No pending application record for pid " + pid
6378                    + " (IApplicationThread " + thread + "); dropping process");
6379            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6380            if (pid > 0 && pid != MY_PID) {
6381                Process.killProcessQuiet(pid);
6382                //TODO: killProcessGroup(app.info.uid, pid);
6383            } else {
6384                try {
6385                    thread.scheduleExit();
6386                } catch (Exception e) {
6387                    // Ignore exceptions.
6388                }
6389            }
6390            return false;
6391        }
6392
6393        // If this application record is still attached to a previous
6394        // process, clean it up now.
6395        if (app.thread != null) {
6396            handleAppDiedLocked(app, true, true);
6397        }
6398
6399        // Tell the process all about itself.
6400
6401        if (DEBUG_ALL) Slog.v(
6402                TAG, "Binding process pid " + pid + " to record " + app);
6403
6404        final String processName = app.processName;
6405        try {
6406            AppDeathRecipient adr = new AppDeathRecipient(
6407                    app, pid, thread);
6408            thread.asBinder().linkToDeath(adr, 0);
6409            app.deathRecipient = adr;
6410        } catch (RemoteException e) {
6411            app.resetPackageList(mProcessStats);
6412            startProcessLocked(app, "link fail", processName);
6413            return false;
6414        }
6415
6416        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6417
6418        app.makeActive(thread, mProcessStats);
6419        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6420        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6421        app.forcingToForeground = null;
6422        updateProcessForegroundLocked(app, false, false);
6423        app.hasShownUi = false;
6424        app.debugging = false;
6425        app.cached = false;
6426        app.killedByAm = false;
6427
6428        // We carefully use the same state that PackageManager uses for
6429        // filtering, since we use this flag to decide if we need to install
6430        // providers when user is unlocked later
6431        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6432
6433        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6434
6435        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6436        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6437
6438        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6439            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6440            msg.obj = app;
6441            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6442        }
6443
6444        if (!normalMode) {
6445            Slog.i(TAG, "Launching preboot mode app: " + app);
6446        }
6447
6448        if (DEBUG_ALL) Slog.v(
6449            TAG, "New app record " + app
6450            + " thread=" + thread.asBinder() + " pid=" + pid);
6451        try {
6452            int testMode = IApplicationThread.DEBUG_OFF;
6453            if (mDebugApp != null && mDebugApp.equals(processName)) {
6454                testMode = mWaitForDebugger
6455                    ? IApplicationThread.DEBUG_WAIT
6456                    : IApplicationThread.DEBUG_ON;
6457                app.debugging = true;
6458                if (mDebugTransient) {
6459                    mDebugApp = mOrigDebugApp;
6460                    mWaitForDebugger = mOrigWaitForDebugger;
6461                }
6462            }
6463            String profileFile = app.instrumentationProfileFile;
6464            ParcelFileDescriptor profileFd = null;
6465            int samplingInterval = 0;
6466            boolean profileAutoStop = false;
6467            if (mProfileApp != null && mProfileApp.equals(processName)) {
6468                mProfileProc = app;
6469                profileFile = mProfileFile;
6470                profileFd = mProfileFd;
6471                samplingInterval = mSamplingInterval;
6472                profileAutoStop = mAutoStopProfiler;
6473            }
6474            boolean enableTrackAllocation = false;
6475            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6476                enableTrackAllocation = true;
6477                mTrackAllocationApp = null;
6478            }
6479
6480            // If the app is being launched for restore or full backup, set it up specially
6481            boolean isRestrictedBackupMode = false;
6482            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6483                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6484                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6485                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6486                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6487            }
6488
6489            if (app.instrumentationClass != null) {
6490                notifyPackageUse(app.instrumentationClass.getPackageName(),
6491                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6492            }
6493            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6494                    + processName + " with config " + mConfiguration);
6495            ApplicationInfo appInfo = app.instrumentationInfo != null
6496                    ? app.instrumentationInfo : app.info;
6497            app.compat = compatibilityInfoForPackageLocked(appInfo);
6498            if (profileFd != null) {
6499                profileFd = profileFd.dup();
6500            }
6501            ProfilerInfo profilerInfo = profileFile == null ? null
6502                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6503            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6504                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6505                    app.instrumentationUiAutomationConnection, testMode,
6506                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6507                    isRestrictedBackupMode || !normalMode, app.persistent,
6508                    new Configuration(mConfiguration), app.compat,
6509                    getCommonServicesLocked(app.isolated),
6510                    mCoreSettingsObserver.getCoreSettingsLocked());
6511            updateLruProcessLocked(app, false, null);
6512            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6513        } catch (Exception e) {
6514            // todo: Yikes!  What should we do?  For now we will try to
6515            // start another process, but that could easily get us in
6516            // an infinite loop of restarting processes...
6517            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6518
6519            app.resetPackageList(mProcessStats);
6520            app.unlinkDeathRecipient();
6521            startProcessLocked(app, "bind fail", processName);
6522            return false;
6523        }
6524
6525        // Remove this record from the list of starting applications.
6526        mPersistentStartingProcesses.remove(app);
6527        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6528                "Attach application locked removing on hold: " + app);
6529        mProcessesOnHold.remove(app);
6530
6531        boolean badApp = false;
6532        boolean didSomething = false;
6533
6534        // See if the top visible activity is waiting to run in this process...
6535        if (normalMode) {
6536            try {
6537                if (mStackSupervisor.attachApplicationLocked(app)) {
6538                    didSomething = true;
6539                }
6540            } catch (Exception e) {
6541                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6542                badApp = true;
6543            }
6544        }
6545
6546        // Find any services that should be running in this process...
6547        if (!badApp) {
6548            try {
6549                didSomething |= mServices.attachApplicationLocked(app, processName);
6550            } catch (Exception e) {
6551                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6552                badApp = true;
6553            }
6554        }
6555
6556        // Check if a next-broadcast receiver is in this process...
6557        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6558            try {
6559                didSomething |= sendPendingBroadcastsLocked(app);
6560            } catch (Exception e) {
6561                // If the app died trying to launch the receiver we declare it 'bad'
6562                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6563                badApp = true;
6564            }
6565        }
6566
6567        // Check whether the next backup agent is in this process...
6568        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6569            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6570                    "New app is backup target, launching agent for " + app);
6571            notifyPackageUse(mBackupTarget.appInfo.packageName,
6572                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6573            try {
6574                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6575                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6576                        mBackupTarget.backupMode);
6577            } catch (Exception e) {
6578                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6579                badApp = true;
6580            }
6581        }
6582
6583        if (badApp) {
6584            app.kill("error during init", true);
6585            handleAppDiedLocked(app, false, true);
6586            return false;
6587        }
6588
6589        if (!didSomething) {
6590            updateOomAdjLocked();
6591        }
6592
6593        return true;
6594    }
6595
6596    @Override
6597    public final void attachApplication(IApplicationThread thread) {
6598        synchronized (this) {
6599            int callingPid = Binder.getCallingPid();
6600            final long origId = Binder.clearCallingIdentity();
6601            attachApplicationLocked(thread, callingPid);
6602            Binder.restoreCallingIdentity(origId);
6603        }
6604    }
6605
6606    @Override
6607    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6608        final long origId = Binder.clearCallingIdentity();
6609        synchronized (this) {
6610            ActivityStack stack = ActivityRecord.getStackLocked(token);
6611            if (stack != null) {
6612                ActivityRecord r =
6613                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6614                if (stopProfiling) {
6615                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6616                        try {
6617                            mProfileFd.close();
6618                        } catch (IOException e) {
6619                        }
6620                        clearProfilerLocked();
6621                    }
6622                }
6623            }
6624        }
6625        Binder.restoreCallingIdentity(origId);
6626    }
6627
6628    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6629        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6630                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6631    }
6632
6633    void enableScreenAfterBoot() {
6634        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6635                SystemClock.uptimeMillis());
6636        mWindowManager.enableScreenAfterBoot();
6637
6638        synchronized (this) {
6639            updateEventDispatchingLocked();
6640        }
6641    }
6642
6643    @Override
6644    public void showBootMessage(final CharSequence msg, final boolean always) {
6645        if (Binder.getCallingUid() != Process.myUid()) {
6646            // These days only the core system can call this, so apps can't get in
6647            // the way of what we show about running them.
6648        }
6649        mWindowManager.showBootMessage(msg, always);
6650    }
6651
6652    @Override
6653    public void keyguardWaitingForActivityDrawn() {
6654        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6655        final long token = Binder.clearCallingIdentity();
6656        try {
6657            synchronized (this) {
6658                if (DEBUG_LOCKSCREEN) logLockScreen("");
6659                mWindowManager.keyguardWaitingForActivityDrawn();
6660                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6661                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6662                    updateSleepIfNeededLocked();
6663                }
6664            }
6665        } finally {
6666            Binder.restoreCallingIdentity(token);
6667        }
6668    }
6669
6670    @Override
6671    public void keyguardGoingAway(int flags) {
6672        enforceNotIsolatedCaller("keyguardGoingAway");
6673        final long token = Binder.clearCallingIdentity();
6674        try {
6675            synchronized (this) {
6676                if (DEBUG_LOCKSCREEN) logLockScreen("");
6677                mWindowManager.keyguardGoingAway(flags);
6678                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6679                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6680                    updateSleepIfNeededLocked();
6681
6682                    // Some stack visibility might change (e.g. docked stack)
6683                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6684                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6685                }
6686            }
6687        } finally {
6688            Binder.restoreCallingIdentity(token);
6689        }
6690    }
6691
6692    final void finishBooting() {
6693        synchronized (this) {
6694            if (!mBootAnimationComplete) {
6695                mCallFinishBooting = true;
6696                return;
6697            }
6698            mCallFinishBooting = false;
6699        }
6700
6701        ArraySet<String> completedIsas = new ArraySet<String>();
6702        for (String abi : Build.SUPPORTED_ABIS) {
6703            Process.establishZygoteConnectionForAbi(abi);
6704            final String instructionSet = VMRuntime.getInstructionSet(abi);
6705            if (!completedIsas.contains(instructionSet)) {
6706                try {
6707                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6708                } catch (InstallerException e) {
6709                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6710                            e.getMessage() +")");
6711                }
6712                completedIsas.add(instructionSet);
6713            }
6714        }
6715
6716        IntentFilter pkgFilter = new IntentFilter();
6717        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6718        pkgFilter.addDataScheme("package");
6719        mContext.registerReceiver(new BroadcastReceiver() {
6720            @Override
6721            public void onReceive(Context context, Intent intent) {
6722                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6723                if (pkgs != null) {
6724                    for (String pkg : pkgs) {
6725                        synchronized (ActivityManagerService.this) {
6726                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6727                                    0, "query restart")) {
6728                                setResultCode(Activity.RESULT_OK);
6729                                return;
6730                            }
6731                        }
6732                    }
6733                }
6734            }
6735        }, pkgFilter);
6736
6737        IntentFilter dumpheapFilter = new IntentFilter();
6738        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6739        mContext.registerReceiver(new BroadcastReceiver() {
6740            @Override
6741            public void onReceive(Context context, Intent intent) {
6742                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6743                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6744                } else {
6745                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6746                }
6747            }
6748        }, dumpheapFilter);
6749
6750        // Let system services know.
6751        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6752
6753        synchronized (this) {
6754            // Ensure that any processes we had put on hold are now started
6755            // up.
6756            final int NP = mProcessesOnHold.size();
6757            if (NP > 0) {
6758                ArrayList<ProcessRecord> procs =
6759                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6760                for (int ip=0; ip<NP; ip++) {
6761                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6762                            + procs.get(ip));
6763                    startProcessLocked(procs.get(ip), "on-hold", null);
6764                }
6765            }
6766
6767            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6768                // Start looking for apps that are abusing wake locks.
6769                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6770                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6771                // Tell anyone interested that we are done booting!
6772                SystemProperties.set("sys.boot_completed", "1");
6773
6774                // And trigger dev.bootcomplete if we are not showing encryption progress
6775                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6776                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6777                    SystemProperties.set("dev.bootcomplete", "1");
6778                }
6779                mUserController.sendBootCompletedLocked(
6780                        new IIntentReceiver.Stub() {
6781                            @Override
6782                            public void performReceive(Intent intent, int resultCode,
6783                                    String data, Bundle extras, boolean ordered,
6784                                    boolean sticky, int sendingUser) {
6785                                synchronized (ActivityManagerService.this) {
6786                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6787                                            true, false);
6788                                }
6789                            }
6790                        });
6791                scheduleStartProfilesLocked();
6792            }
6793        }
6794    }
6795
6796    @Override
6797    public void bootAnimationComplete() {
6798        final boolean callFinishBooting;
6799        synchronized (this) {
6800            callFinishBooting = mCallFinishBooting;
6801            mBootAnimationComplete = true;
6802        }
6803        if (callFinishBooting) {
6804            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6805            finishBooting();
6806            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6807        }
6808    }
6809
6810    final void ensureBootCompleted() {
6811        boolean booting;
6812        boolean enableScreen;
6813        synchronized (this) {
6814            booting = mBooting;
6815            mBooting = false;
6816            enableScreen = !mBooted;
6817            mBooted = true;
6818        }
6819
6820        if (booting) {
6821            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6822            finishBooting();
6823            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6824        }
6825
6826        if (enableScreen) {
6827            enableScreenAfterBoot();
6828        }
6829    }
6830
6831    @Override
6832    public final void activityResumed(IBinder token) {
6833        final long origId = Binder.clearCallingIdentity();
6834        synchronized(this) {
6835            ActivityStack stack = ActivityRecord.getStackLocked(token);
6836            if (stack != null) {
6837                stack.activityResumedLocked(token);
6838            }
6839        }
6840        Binder.restoreCallingIdentity(origId);
6841    }
6842
6843    @Override
6844    public final void activityPaused(IBinder token) {
6845        final long origId = Binder.clearCallingIdentity();
6846        synchronized(this) {
6847            ActivityStack stack = ActivityRecord.getStackLocked(token);
6848            if (stack != null) {
6849                stack.activityPausedLocked(token, false);
6850            }
6851        }
6852        Binder.restoreCallingIdentity(origId);
6853    }
6854
6855    @Override
6856    public final void activityStopped(IBinder token, Bundle icicle,
6857            PersistableBundle persistentState, CharSequence description) {
6858        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6859
6860        // Refuse possible leaked file descriptors
6861        if (icicle != null && icicle.hasFileDescriptors()) {
6862            throw new IllegalArgumentException("File descriptors passed in Bundle");
6863        }
6864
6865        final long origId = Binder.clearCallingIdentity();
6866
6867        synchronized (this) {
6868            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6869            if (r != null) {
6870                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6871            }
6872        }
6873
6874        trimApplications();
6875
6876        Binder.restoreCallingIdentity(origId);
6877    }
6878
6879    @Override
6880    public final void activityDestroyed(IBinder token) {
6881        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6882        synchronized (this) {
6883            ActivityStack stack = ActivityRecord.getStackLocked(token);
6884            if (stack != null) {
6885                stack.activityDestroyedLocked(token, "activityDestroyed");
6886            }
6887        }
6888    }
6889
6890    @Override
6891    public final void activityRelaunched(IBinder token) {
6892        final long origId = Binder.clearCallingIdentity();
6893        synchronized (this) {
6894            mStackSupervisor.activityRelaunchedLocked(token);
6895        }
6896        Binder.restoreCallingIdentity(origId);
6897    }
6898
6899    @Override
6900    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6901            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6902        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6903                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6904        synchronized (this) {
6905            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6906            if (record == null) {
6907                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6908                        + "found for: " + token);
6909            }
6910            record.setSizeConfigurations(horizontalSizeConfiguration,
6911                    verticalSizeConfigurations, smallestSizeConfigurations);
6912        }
6913    }
6914
6915    @Override
6916    public final void backgroundResourcesReleased(IBinder token) {
6917        final long origId = Binder.clearCallingIdentity();
6918        try {
6919            synchronized (this) {
6920                ActivityStack stack = ActivityRecord.getStackLocked(token);
6921                if (stack != null) {
6922                    stack.backgroundResourcesReleased();
6923                }
6924            }
6925        } finally {
6926            Binder.restoreCallingIdentity(origId);
6927        }
6928    }
6929
6930    @Override
6931    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6932        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6933    }
6934
6935    @Override
6936    public final void notifyEnterAnimationComplete(IBinder token) {
6937        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6938    }
6939
6940    @Override
6941    public String getCallingPackage(IBinder token) {
6942        synchronized (this) {
6943            ActivityRecord r = getCallingRecordLocked(token);
6944            return r != null ? r.info.packageName : null;
6945        }
6946    }
6947
6948    @Override
6949    public ComponentName getCallingActivity(IBinder token) {
6950        synchronized (this) {
6951            ActivityRecord r = getCallingRecordLocked(token);
6952            return r != null ? r.intent.getComponent() : null;
6953        }
6954    }
6955
6956    private ActivityRecord getCallingRecordLocked(IBinder token) {
6957        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6958        if (r == null) {
6959            return null;
6960        }
6961        return r.resultTo;
6962    }
6963
6964    @Override
6965    public ComponentName getActivityClassForToken(IBinder token) {
6966        synchronized(this) {
6967            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6968            if (r == null) {
6969                return null;
6970            }
6971            return r.intent.getComponent();
6972        }
6973    }
6974
6975    @Override
6976    public String getPackageForToken(IBinder token) {
6977        synchronized(this) {
6978            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6979            if (r == null) {
6980                return null;
6981            }
6982            return r.packageName;
6983        }
6984    }
6985
6986    @Override
6987    public boolean isRootVoiceInteraction(IBinder token) {
6988        synchronized(this) {
6989            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6990            if (r == null) {
6991                return false;
6992            }
6993            return r.rootVoiceInteraction;
6994        }
6995    }
6996
6997    @Override
6998    public IIntentSender getIntentSender(int type,
6999            String packageName, IBinder token, String resultWho,
7000            int requestCode, Intent[] intents, String[] resolvedTypes,
7001            int flags, Bundle bOptions, int userId) {
7002        enforceNotIsolatedCaller("getIntentSender");
7003        // Refuse possible leaked file descriptors
7004        if (intents != null) {
7005            if (intents.length < 1) {
7006                throw new IllegalArgumentException("Intents array length must be >= 1");
7007            }
7008            for (int i=0; i<intents.length; i++) {
7009                Intent intent = intents[i];
7010                if (intent != null) {
7011                    if (intent.hasFileDescriptors()) {
7012                        throw new IllegalArgumentException("File descriptors passed in Intent");
7013                    }
7014                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7015                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7016                        throw new IllegalArgumentException(
7017                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7018                    }
7019                    intents[i] = new Intent(intent);
7020                }
7021            }
7022            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7023                throw new IllegalArgumentException(
7024                        "Intent array length does not match resolvedTypes length");
7025            }
7026        }
7027        if (bOptions != null) {
7028            if (bOptions.hasFileDescriptors()) {
7029                throw new IllegalArgumentException("File descriptors passed in options");
7030            }
7031        }
7032
7033        synchronized(this) {
7034            int callingUid = Binder.getCallingUid();
7035            int origUserId = userId;
7036            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7037                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7038                    ALLOW_NON_FULL, "getIntentSender", null);
7039            if (origUserId == UserHandle.USER_CURRENT) {
7040                // We don't want to evaluate this until the pending intent is
7041                // actually executed.  However, we do want to always do the
7042                // security checking for it above.
7043                userId = UserHandle.USER_CURRENT;
7044            }
7045            try {
7046                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7047                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7048                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7049                    if (!UserHandle.isSameApp(callingUid, uid)) {
7050                        String msg = "Permission Denial: getIntentSender() from pid="
7051                            + Binder.getCallingPid()
7052                            + ", uid=" + Binder.getCallingUid()
7053                            + ", (need uid=" + uid + ")"
7054                            + " is not allowed to send as package " + packageName;
7055                        Slog.w(TAG, msg);
7056                        throw new SecurityException(msg);
7057                    }
7058                }
7059
7060                return getIntentSenderLocked(type, packageName, callingUid, userId,
7061                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7062
7063            } catch (RemoteException e) {
7064                throw new SecurityException(e);
7065            }
7066        }
7067    }
7068
7069    IIntentSender getIntentSenderLocked(int type, String packageName,
7070            int callingUid, int userId, IBinder token, String resultWho,
7071            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7072            Bundle bOptions) {
7073        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7074        ActivityRecord activity = null;
7075        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7076            activity = ActivityRecord.isInStackLocked(token);
7077            if (activity == null) {
7078                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7079                return null;
7080            }
7081            if (activity.finishing) {
7082                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7083                return null;
7084            }
7085        }
7086
7087        // We're going to be splicing together extras before sending, so we're
7088        // okay poking into any contained extras.
7089        if (intents != null) {
7090            for (int i = 0; i < intents.length; i++) {
7091                intents[i].setDefusable(true);
7092            }
7093        }
7094        Bundle.setDefusable(bOptions, true);
7095
7096        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7097        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7098        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7099        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7100                |PendingIntent.FLAG_UPDATE_CURRENT);
7101
7102        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7103                type, packageName, activity, resultWho,
7104                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7105        WeakReference<PendingIntentRecord> ref;
7106        ref = mIntentSenderRecords.get(key);
7107        PendingIntentRecord rec = ref != null ? ref.get() : null;
7108        if (rec != null) {
7109            if (!cancelCurrent) {
7110                if (updateCurrent) {
7111                    if (rec.key.requestIntent != null) {
7112                        rec.key.requestIntent.replaceExtras(intents != null ?
7113                                intents[intents.length - 1] : null);
7114                    }
7115                    if (intents != null) {
7116                        intents[intents.length-1] = rec.key.requestIntent;
7117                        rec.key.allIntents = intents;
7118                        rec.key.allResolvedTypes = resolvedTypes;
7119                    } else {
7120                        rec.key.allIntents = null;
7121                        rec.key.allResolvedTypes = null;
7122                    }
7123                }
7124                return rec;
7125            }
7126            rec.canceled = true;
7127            mIntentSenderRecords.remove(key);
7128        }
7129        if (noCreate) {
7130            return rec;
7131        }
7132        rec = new PendingIntentRecord(this, key, callingUid);
7133        mIntentSenderRecords.put(key, rec.ref);
7134        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7135            if (activity.pendingResults == null) {
7136                activity.pendingResults
7137                        = new HashSet<WeakReference<PendingIntentRecord>>();
7138            }
7139            activity.pendingResults.add(rec.ref);
7140        }
7141        return rec;
7142    }
7143
7144    @Override
7145    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7146            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7147        if (target instanceof PendingIntentRecord) {
7148            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7149                    finishedReceiver, requiredPermission, options);
7150        } else {
7151            if (intent == null) {
7152                // Weird case: someone has given us their own custom IIntentSender, and now
7153                // they have someone else trying to send to it but of course this isn't
7154                // really a PendingIntent, so there is no base Intent, and the caller isn't
7155                // supplying an Intent... but we never want to dispatch a null Intent to
7156                // a receiver, so um...  let's make something up.
7157                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7158                intent = new Intent(Intent.ACTION_MAIN);
7159            }
7160            try {
7161                target.send(code, intent, resolvedType, null, requiredPermission, options);
7162            } catch (RemoteException e) {
7163            }
7164            // Platform code can rely on getting a result back when the send is done, but if
7165            // this intent sender is from outside of the system we can't rely on it doing that.
7166            // So instead we don't give it the result receiver, and instead just directly
7167            // report the finish immediately.
7168            if (finishedReceiver != null) {
7169                try {
7170                    finishedReceiver.performReceive(intent, 0,
7171                            null, null, false, false, UserHandle.getCallingUserId());
7172                } catch (RemoteException e) {
7173                }
7174            }
7175            return 0;
7176        }
7177    }
7178
7179    /**
7180     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7181     *
7182     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7183     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7184     */
7185    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7186        if (DEBUG_WHITELISTS) {
7187            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7188                    + targetUid + ", " + duration + ")");
7189        }
7190        synchronized (mPidsSelfLocked) {
7191            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7192            if (pr == null) {
7193                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7194                return;
7195            }
7196            if (!pr.whitelistManager) {
7197                if (DEBUG_WHITELISTS) {
7198                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7199                            + callerPid + " is not allowed");
7200                }
7201                return;
7202            }
7203        }
7204
7205        final long token = Binder.clearCallingIdentity();
7206        try {
7207            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7208                    true, "pe from uid:" + callerUid);
7209        } finally {
7210            Binder.restoreCallingIdentity(token);
7211        }
7212    }
7213
7214    @Override
7215    public void cancelIntentSender(IIntentSender sender) {
7216        if (!(sender instanceof PendingIntentRecord)) {
7217            return;
7218        }
7219        synchronized(this) {
7220            PendingIntentRecord rec = (PendingIntentRecord)sender;
7221            try {
7222                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7223                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7224                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7225                    String msg = "Permission Denial: cancelIntentSender() from pid="
7226                        + Binder.getCallingPid()
7227                        + ", uid=" + Binder.getCallingUid()
7228                        + " is not allowed to cancel packges "
7229                        + rec.key.packageName;
7230                    Slog.w(TAG, msg);
7231                    throw new SecurityException(msg);
7232                }
7233            } catch (RemoteException e) {
7234                throw new SecurityException(e);
7235            }
7236            cancelIntentSenderLocked(rec, true);
7237        }
7238    }
7239
7240    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7241        rec.canceled = true;
7242        mIntentSenderRecords.remove(rec.key);
7243        if (cleanActivity && rec.key.activity != null) {
7244            rec.key.activity.pendingResults.remove(rec.ref);
7245        }
7246    }
7247
7248    @Override
7249    public String getPackageForIntentSender(IIntentSender pendingResult) {
7250        if (!(pendingResult instanceof PendingIntentRecord)) {
7251            return null;
7252        }
7253        try {
7254            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7255            return res.key.packageName;
7256        } catch (ClassCastException e) {
7257        }
7258        return null;
7259    }
7260
7261    @Override
7262    public int getUidForIntentSender(IIntentSender sender) {
7263        if (sender instanceof PendingIntentRecord) {
7264            try {
7265                PendingIntentRecord res = (PendingIntentRecord)sender;
7266                return res.uid;
7267            } catch (ClassCastException e) {
7268            }
7269        }
7270        return -1;
7271    }
7272
7273    @Override
7274    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7275        if (!(pendingResult instanceof PendingIntentRecord)) {
7276            return false;
7277        }
7278        try {
7279            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7280            if (res.key.allIntents == null) {
7281                return false;
7282            }
7283            for (int i=0; i<res.key.allIntents.length; i++) {
7284                Intent intent = res.key.allIntents[i];
7285                if (intent.getPackage() != null && intent.getComponent() != null) {
7286                    return false;
7287                }
7288            }
7289            return true;
7290        } catch (ClassCastException e) {
7291        }
7292        return false;
7293    }
7294
7295    @Override
7296    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7297        if (!(pendingResult instanceof PendingIntentRecord)) {
7298            return false;
7299        }
7300        try {
7301            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7302            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7303                return true;
7304            }
7305            return false;
7306        } catch (ClassCastException e) {
7307        }
7308        return false;
7309    }
7310
7311    @Override
7312    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7313        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7314                "getIntentForIntentSender()");
7315        if (!(pendingResult instanceof PendingIntentRecord)) {
7316            return null;
7317        }
7318        try {
7319            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7320            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7321        } catch (ClassCastException e) {
7322        }
7323        return null;
7324    }
7325
7326    @Override
7327    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7328        if (!(pendingResult instanceof PendingIntentRecord)) {
7329            return null;
7330        }
7331        try {
7332            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7333            synchronized (this) {
7334                return getTagForIntentSenderLocked(res, prefix);
7335            }
7336        } catch (ClassCastException e) {
7337        }
7338        return null;
7339    }
7340
7341    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7342        final Intent intent = res.key.requestIntent;
7343        if (intent != null) {
7344            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7345                    || res.lastTagPrefix.equals(prefix))) {
7346                return res.lastTag;
7347            }
7348            res.lastTagPrefix = prefix;
7349            final StringBuilder sb = new StringBuilder(128);
7350            if (prefix != null) {
7351                sb.append(prefix);
7352            }
7353            if (intent.getAction() != null) {
7354                sb.append(intent.getAction());
7355            } else if (intent.getComponent() != null) {
7356                intent.getComponent().appendShortString(sb);
7357            } else {
7358                sb.append("?");
7359            }
7360            return res.lastTag = sb.toString();
7361        }
7362        return null;
7363    }
7364
7365    @Override
7366    public void setProcessLimit(int max) {
7367        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7368                "setProcessLimit()");
7369        synchronized (this) {
7370            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7371            mProcessLimitOverride = max;
7372        }
7373        trimApplications();
7374    }
7375
7376    @Override
7377    public int getProcessLimit() {
7378        synchronized (this) {
7379            return mProcessLimitOverride;
7380        }
7381    }
7382
7383    void foregroundTokenDied(ForegroundToken token) {
7384        synchronized (ActivityManagerService.this) {
7385            synchronized (mPidsSelfLocked) {
7386                ForegroundToken cur
7387                    = mForegroundProcesses.get(token.pid);
7388                if (cur != token) {
7389                    return;
7390                }
7391                mForegroundProcesses.remove(token.pid);
7392                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7393                if (pr == null) {
7394                    return;
7395                }
7396                pr.forcingToForeground = null;
7397                updateProcessForegroundLocked(pr, false, false);
7398            }
7399            updateOomAdjLocked();
7400        }
7401    }
7402
7403    @Override
7404    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7405        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7406                "setProcessForeground()");
7407        synchronized(this) {
7408            boolean changed = false;
7409
7410            synchronized (mPidsSelfLocked) {
7411                ProcessRecord pr = mPidsSelfLocked.get(pid);
7412                if (pr == null && isForeground) {
7413                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7414                    return;
7415                }
7416                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7417                if (oldToken != null) {
7418                    oldToken.token.unlinkToDeath(oldToken, 0);
7419                    mForegroundProcesses.remove(pid);
7420                    if (pr != null) {
7421                        pr.forcingToForeground = null;
7422                    }
7423                    changed = true;
7424                }
7425                if (isForeground && token != null) {
7426                    ForegroundToken newToken = new ForegroundToken() {
7427                        @Override
7428                        public void binderDied() {
7429                            foregroundTokenDied(this);
7430                        }
7431                    };
7432                    newToken.pid = pid;
7433                    newToken.token = token;
7434                    try {
7435                        token.linkToDeath(newToken, 0);
7436                        mForegroundProcesses.put(pid, newToken);
7437                        pr.forcingToForeground = token;
7438                        changed = true;
7439                    } catch (RemoteException e) {
7440                        // If the process died while doing this, we will later
7441                        // do the cleanup with the process death link.
7442                    }
7443                }
7444            }
7445
7446            if (changed) {
7447                updateOomAdjLocked();
7448            }
7449        }
7450    }
7451
7452    @Override
7453    public boolean isAppForeground(int uid) throws RemoteException {
7454        synchronized (this) {
7455            UidRecord uidRec = mActiveUids.get(uid);
7456            if (uidRec == null || uidRec.idle) {
7457                return false;
7458            }
7459            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7460        }
7461    }
7462
7463    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7464    // be guarded by permission checking.
7465    int getUidState(int uid) {
7466        synchronized (this) {
7467            UidRecord uidRec = mActiveUids.get(uid);
7468            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7469        }
7470    }
7471
7472    @Override
7473    public boolean isInMultiWindowMode(IBinder token) {
7474        final long origId = Binder.clearCallingIdentity();
7475        try {
7476            synchronized(this) {
7477                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7478                if (r == null) {
7479                    return false;
7480                }
7481                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7482                return !r.task.mFullscreen;
7483            }
7484        } finally {
7485            Binder.restoreCallingIdentity(origId);
7486        }
7487    }
7488
7489    @Override
7490    public boolean isInPictureInPictureMode(IBinder token) {
7491        final long origId = Binder.clearCallingIdentity();
7492        try {
7493            synchronized(this) {
7494                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7495                if (stack == null) {
7496                    return false;
7497                }
7498                return stack.mStackId == PINNED_STACK_ID;
7499            }
7500        } finally {
7501            Binder.restoreCallingIdentity(origId);
7502        }
7503    }
7504
7505    @Override
7506    public void enterPictureInPictureMode(IBinder token) {
7507        final long origId = Binder.clearCallingIdentity();
7508        try {
7509            synchronized(this) {
7510                if (!mSupportsPictureInPicture) {
7511                    throw new IllegalStateException("enterPictureInPictureMode: "
7512                            + "Device doesn't support picture-in-picture mode.");
7513                }
7514
7515                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7516
7517                if (r == null) {
7518                    throw new IllegalStateException("enterPictureInPictureMode: "
7519                            + "Can't find activity for token=" + token);
7520                }
7521
7522                if (!r.supportsPictureInPicture()) {
7523                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7524                            + "Picture-In-Picture not supported for r=" + r);
7525                }
7526
7527                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7528                // current bounds.
7529                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7530                final Rect bounds = (pinnedStack != null)
7531                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7532
7533                mStackSupervisor.moveActivityToPinnedStackLocked(
7534                        r, "enterPictureInPictureMode", bounds);
7535            }
7536        } finally {
7537            Binder.restoreCallingIdentity(origId);
7538        }
7539    }
7540
7541    // =========================================================
7542    // PROCESS INFO
7543    // =========================================================
7544
7545    static class ProcessInfoService extends IProcessInfoService.Stub {
7546        final ActivityManagerService mActivityManagerService;
7547        ProcessInfoService(ActivityManagerService activityManagerService) {
7548            mActivityManagerService = activityManagerService;
7549        }
7550
7551        @Override
7552        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7553            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7554                    /*in*/ pids, /*out*/ states, null);
7555        }
7556
7557        @Override
7558        public void getProcessStatesAndOomScoresFromPids(
7559                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7560            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7561                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7562        }
7563    }
7564
7565    /**
7566     * For each PID in the given input array, write the current process state
7567     * for that process into the states array, or -1 to indicate that no
7568     * process with the given PID exists. If scores array is provided, write
7569     * the oom score for the process into the scores array, with INVALID_ADJ
7570     * indicating the PID doesn't exist.
7571     */
7572    public void getProcessStatesAndOomScoresForPIDs(
7573            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7574        if (scores != null) {
7575            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7576                    "getProcessStatesAndOomScoresForPIDs()");
7577        }
7578
7579        if (pids == null) {
7580            throw new NullPointerException("pids");
7581        } else if (states == null) {
7582            throw new NullPointerException("states");
7583        } else if (pids.length != states.length) {
7584            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7585        } else if (scores != null && pids.length != scores.length) {
7586            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7587        }
7588
7589        synchronized (mPidsSelfLocked) {
7590            for (int i = 0; i < pids.length; i++) {
7591                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7592                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7593                        pr.curProcState;
7594                if (scores != null) {
7595                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7596                }
7597            }
7598        }
7599    }
7600
7601    // =========================================================
7602    // PERMISSIONS
7603    // =========================================================
7604
7605    static class PermissionController extends IPermissionController.Stub {
7606        ActivityManagerService mActivityManagerService;
7607        PermissionController(ActivityManagerService activityManagerService) {
7608            mActivityManagerService = activityManagerService;
7609        }
7610
7611        @Override
7612        public boolean checkPermission(String permission, int pid, int uid) {
7613            return mActivityManagerService.checkPermission(permission, pid,
7614                    uid) == PackageManager.PERMISSION_GRANTED;
7615        }
7616
7617        @Override
7618        public String[] getPackagesForUid(int uid) {
7619            return mActivityManagerService.mContext.getPackageManager()
7620                    .getPackagesForUid(uid);
7621        }
7622
7623        @Override
7624        public boolean isRuntimePermission(String permission) {
7625            try {
7626                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7627                        .getPermissionInfo(permission, 0);
7628                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7629            } catch (NameNotFoundException nnfe) {
7630                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7631            }
7632            return false;
7633        }
7634    }
7635
7636    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7637        @Override
7638        public int checkComponentPermission(String permission, int pid, int uid,
7639                int owningUid, boolean exported) {
7640            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7641                    owningUid, exported);
7642        }
7643
7644        @Override
7645        public Object getAMSLock() {
7646            return ActivityManagerService.this;
7647        }
7648    }
7649
7650    /**
7651     * This can be called with or without the global lock held.
7652     */
7653    int checkComponentPermission(String permission, int pid, int uid,
7654            int owningUid, boolean exported) {
7655        if (pid == MY_PID) {
7656            return PackageManager.PERMISSION_GRANTED;
7657        }
7658        return ActivityManager.checkComponentPermission(permission, uid,
7659                owningUid, exported);
7660    }
7661
7662    /**
7663     * As the only public entry point for permissions checking, this method
7664     * can enforce the semantic that requesting a check on a null global
7665     * permission is automatically denied.  (Internally a null permission
7666     * string is used when calling {@link #checkComponentPermission} in cases
7667     * when only uid-based security is needed.)
7668     *
7669     * This can be called with or without the global lock held.
7670     */
7671    @Override
7672    public int checkPermission(String permission, int pid, int uid) {
7673        if (permission == null) {
7674            return PackageManager.PERMISSION_DENIED;
7675        }
7676        return checkComponentPermission(permission, pid, uid, -1, true);
7677    }
7678
7679    @Override
7680    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7681        if (permission == null) {
7682            return PackageManager.PERMISSION_DENIED;
7683        }
7684
7685        // We might be performing an operation on behalf of an indirect binder
7686        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7687        // client identity accordingly before proceeding.
7688        Identity tlsIdentity = sCallerIdentity.get();
7689        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7690            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7691                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7692            uid = tlsIdentity.uid;
7693            pid = tlsIdentity.pid;
7694        }
7695
7696        return checkComponentPermission(permission, pid, uid, -1, true);
7697    }
7698
7699    /**
7700     * Binder IPC calls go through the public entry point.
7701     * This can be called with or without the global lock held.
7702     */
7703    int checkCallingPermission(String permission) {
7704        return checkPermission(permission,
7705                Binder.getCallingPid(),
7706                UserHandle.getAppId(Binder.getCallingUid()));
7707    }
7708
7709    /**
7710     * This can be called with or without the global lock held.
7711     */
7712    void enforceCallingPermission(String permission, String func) {
7713        if (checkCallingPermission(permission)
7714                == PackageManager.PERMISSION_GRANTED) {
7715            return;
7716        }
7717
7718        String msg = "Permission Denial: " + func + " from pid="
7719                + Binder.getCallingPid()
7720                + ", uid=" + Binder.getCallingUid()
7721                + " requires " + permission;
7722        Slog.w(TAG, msg);
7723        throw new SecurityException(msg);
7724    }
7725
7726    /**
7727     * Determine if UID is holding permissions required to access {@link Uri} in
7728     * the given {@link ProviderInfo}. Final permission checking is always done
7729     * in {@link ContentProvider}.
7730     */
7731    private final boolean checkHoldingPermissionsLocked(
7732            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7733        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7734                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7735        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7736            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7737                    != PERMISSION_GRANTED) {
7738                return false;
7739            }
7740        }
7741        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7742    }
7743
7744    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7745            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7746        if (pi.applicationInfo.uid == uid) {
7747            return true;
7748        } else if (!pi.exported) {
7749            return false;
7750        }
7751
7752        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7753        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7754        try {
7755            // check if target holds top-level <provider> permissions
7756            if (!readMet && pi.readPermission != null && considerUidPermissions
7757                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7758                readMet = true;
7759            }
7760            if (!writeMet && pi.writePermission != null && considerUidPermissions
7761                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7762                writeMet = true;
7763            }
7764
7765            // track if unprotected read/write is allowed; any denied
7766            // <path-permission> below removes this ability
7767            boolean allowDefaultRead = pi.readPermission == null;
7768            boolean allowDefaultWrite = pi.writePermission == null;
7769
7770            // check if target holds any <path-permission> that match uri
7771            final PathPermission[] pps = pi.pathPermissions;
7772            if (pps != null) {
7773                final String path = grantUri.uri.getPath();
7774                int i = pps.length;
7775                while (i > 0 && (!readMet || !writeMet)) {
7776                    i--;
7777                    PathPermission pp = pps[i];
7778                    if (pp.match(path)) {
7779                        if (!readMet) {
7780                            final String pprperm = pp.getReadPermission();
7781                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7782                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7783                                    + ": match=" + pp.match(path)
7784                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7785                            if (pprperm != null) {
7786                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7787                                        == PERMISSION_GRANTED) {
7788                                    readMet = true;
7789                                } else {
7790                                    allowDefaultRead = false;
7791                                }
7792                            }
7793                        }
7794                        if (!writeMet) {
7795                            final String ppwperm = pp.getWritePermission();
7796                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7797                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7798                                    + ": match=" + pp.match(path)
7799                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7800                            if (ppwperm != null) {
7801                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7802                                        == PERMISSION_GRANTED) {
7803                                    writeMet = true;
7804                                } else {
7805                                    allowDefaultWrite = false;
7806                                }
7807                            }
7808                        }
7809                    }
7810                }
7811            }
7812
7813            // grant unprotected <provider> read/write, if not blocked by
7814            // <path-permission> above
7815            if (allowDefaultRead) readMet = true;
7816            if (allowDefaultWrite) writeMet = true;
7817
7818        } catch (RemoteException e) {
7819            return false;
7820        }
7821
7822        return readMet && writeMet;
7823    }
7824
7825    public int getAppStartMode(int uid, String packageName) {
7826        synchronized (this) {
7827            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7828        }
7829    }
7830
7831    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7832            boolean allowWhenForeground) {
7833        UidRecord uidRec = mActiveUids.get(uid);
7834        if (!mLenientBackgroundCheck) {
7835            if (!allowWhenForeground || uidRec == null
7836                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7837                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7838                        packageName) != AppOpsManager.MODE_ALLOWED) {
7839                    return ActivityManager.APP_START_MODE_DELAYED;
7840                }
7841            }
7842
7843        } else if (uidRec == null || uidRec.idle) {
7844            if (callingPid >= 0) {
7845                ProcessRecord proc;
7846                synchronized (mPidsSelfLocked) {
7847                    proc = mPidsSelfLocked.get(callingPid);
7848                }
7849                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7850                    // Whoever is instigating this is in the foreground, so we will allow it
7851                    // to go through.
7852                    return ActivityManager.APP_START_MODE_NORMAL;
7853                }
7854            }
7855            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7856                    != AppOpsManager.MODE_ALLOWED) {
7857                return ActivityManager.APP_START_MODE_DELAYED;
7858            }
7859        }
7860        return ActivityManager.APP_START_MODE_NORMAL;
7861    }
7862
7863    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7864        ProviderInfo pi = null;
7865        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7866        if (cpr != null) {
7867            pi = cpr.info;
7868        } else {
7869            try {
7870                pi = AppGlobals.getPackageManager().resolveContentProvider(
7871                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7872                        userHandle);
7873            } catch (RemoteException ex) {
7874            }
7875        }
7876        return pi;
7877    }
7878
7879    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7880        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7881        if (targetUris != null) {
7882            return targetUris.get(grantUri);
7883        }
7884        return null;
7885    }
7886
7887    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7888            String targetPkg, int targetUid, GrantUri grantUri) {
7889        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7890        if (targetUris == null) {
7891            targetUris = Maps.newArrayMap();
7892            mGrantedUriPermissions.put(targetUid, targetUris);
7893        }
7894
7895        UriPermission perm = targetUris.get(grantUri);
7896        if (perm == null) {
7897            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7898            targetUris.put(grantUri, perm);
7899        }
7900
7901        return perm;
7902    }
7903
7904    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7905            final int modeFlags) {
7906        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7907        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7908                : UriPermission.STRENGTH_OWNED;
7909
7910        // Root gets to do everything.
7911        if (uid == 0) {
7912            return true;
7913        }
7914
7915        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7916        if (perms == null) return false;
7917
7918        // First look for exact match
7919        final UriPermission exactPerm = perms.get(grantUri);
7920        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7921            return true;
7922        }
7923
7924        // No exact match, look for prefixes
7925        final int N = perms.size();
7926        for (int i = 0; i < N; i++) {
7927            final UriPermission perm = perms.valueAt(i);
7928            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7929                    && perm.getStrength(modeFlags) >= minStrength) {
7930                return true;
7931            }
7932        }
7933
7934        return false;
7935    }
7936
7937    /**
7938     * @param uri This uri must NOT contain an embedded userId.
7939     * @param userId The userId in which the uri is to be resolved.
7940     */
7941    @Override
7942    public int checkUriPermission(Uri uri, int pid, int uid,
7943            final int modeFlags, int userId, IBinder callerToken) {
7944        enforceNotIsolatedCaller("checkUriPermission");
7945
7946        // Another redirected-binder-call permissions check as in
7947        // {@link checkPermissionWithToken}.
7948        Identity tlsIdentity = sCallerIdentity.get();
7949        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7950            uid = tlsIdentity.uid;
7951            pid = tlsIdentity.pid;
7952        }
7953
7954        // Our own process gets to do everything.
7955        if (pid == MY_PID) {
7956            return PackageManager.PERMISSION_GRANTED;
7957        }
7958        synchronized (this) {
7959            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7960                    ? PackageManager.PERMISSION_GRANTED
7961                    : PackageManager.PERMISSION_DENIED;
7962        }
7963    }
7964
7965    /**
7966     * Check if the targetPkg can be granted permission to access uri by
7967     * the callingUid using the given modeFlags.  Throws a security exception
7968     * if callingUid is not allowed to do this.  Returns the uid of the target
7969     * if the URI permission grant should be performed; returns -1 if it is not
7970     * needed (for example targetPkg already has permission to access the URI).
7971     * If you already know the uid of the target, you can supply it in
7972     * lastTargetUid else set that to -1.
7973     */
7974    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7975            final int modeFlags, int lastTargetUid) {
7976        if (!Intent.isAccessUriMode(modeFlags)) {
7977            return -1;
7978        }
7979
7980        if (targetPkg != null) {
7981            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                    "Checking grant " + targetPkg + " permission to " + grantUri);
7983        }
7984
7985        final IPackageManager pm = AppGlobals.getPackageManager();
7986
7987        // If this is not a content: uri, we can't do anything with it.
7988        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7989            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7990                    "Can't grant URI permission for non-content URI: " + grantUri);
7991            return -1;
7992        }
7993
7994        final String authority = grantUri.uri.getAuthority();
7995        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7996                MATCH_DEBUG_TRIAGED_MISSING);
7997        if (pi == null) {
7998            Slog.w(TAG, "No content provider found for permission check: " +
7999                    grantUri.uri.toSafeString());
8000            return -1;
8001        }
8002
8003        int targetUid = lastTargetUid;
8004        if (targetUid < 0 && targetPkg != null) {
8005            try {
8006                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8007                        UserHandle.getUserId(callingUid));
8008                if (targetUid < 0) {
8009                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8010                            "Can't grant URI permission no uid for: " + targetPkg);
8011                    return -1;
8012                }
8013            } catch (RemoteException ex) {
8014                return -1;
8015            }
8016        }
8017
8018        if (targetUid >= 0) {
8019            // First...  does the target actually need this permission?
8020            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8021                // No need to grant the target this permission.
8022                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8023                        "Target " + targetPkg + " already has full permission to " + grantUri);
8024                return -1;
8025            }
8026        } else {
8027            // First...  there is no target package, so can anyone access it?
8028            boolean allowed = pi.exported;
8029            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8030                if (pi.readPermission != null) {
8031                    allowed = false;
8032                }
8033            }
8034            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8035                if (pi.writePermission != null) {
8036                    allowed = false;
8037                }
8038            }
8039            if (allowed) {
8040                return -1;
8041            }
8042        }
8043
8044        /* There is a special cross user grant if:
8045         * - The target is on another user.
8046         * - Apps on the current user can access the uri without any uid permissions.
8047         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8048         * grant uri permissions.
8049         */
8050        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8051                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8052                modeFlags, false /*without considering the uid permissions*/);
8053
8054        // Second...  is the provider allowing granting of URI permissions?
8055        if (!specialCrossUserGrant) {
8056            if (!pi.grantUriPermissions) {
8057                throw new SecurityException("Provider " + pi.packageName
8058                        + "/" + pi.name
8059                        + " does not allow granting of Uri permissions (uri "
8060                        + grantUri + ")");
8061            }
8062            if (pi.uriPermissionPatterns != null) {
8063                final int N = pi.uriPermissionPatterns.length;
8064                boolean allowed = false;
8065                for (int i=0; i<N; i++) {
8066                    if (pi.uriPermissionPatterns[i] != null
8067                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8068                        allowed = true;
8069                        break;
8070                    }
8071                }
8072                if (!allowed) {
8073                    throw new SecurityException("Provider " + pi.packageName
8074                            + "/" + pi.name
8075                            + " does not allow granting of permission to path of Uri "
8076                            + grantUri);
8077                }
8078            }
8079        }
8080
8081        // Third...  does the caller itself have permission to access
8082        // this uri?
8083        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8084            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8085                // Require they hold a strong enough Uri permission
8086                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8087                    throw new SecurityException("Uid " + callingUid
8088                            + " does not have permission to uri " + grantUri);
8089                }
8090            }
8091        }
8092        return targetUid;
8093    }
8094
8095    /**
8096     * @param uri This uri must NOT contain an embedded userId.
8097     * @param userId The userId in which the uri is to be resolved.
8098     */
8099    @Override
8100    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8101            final int modeFlags, int userId) {
8102        enforceNotIsolatedCaller("checkGrantUriPermission");
8103        synchronized(this) {
8104            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8105                    new GrantUri(userId, uri, false), modeFlags, -1);
8106        }
8107    }
8108
8109    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8110            final int modeFlags, UriPermissionOwner owner) {
8111        if (!Intent.isAccessUriMode(modeFlags)) {
8112            return;
8113        }
8114
8115        // So here we are: the caller has the assumed permission
8116        // to the uri, and the target doesn't.  Let's now give this to
8117        // the target.
8118
8119        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8121
8122        final String authority = grantUri.uri.getAuthority();
8123        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8124                MATCH_DEBUG_TRIAGED_MISSING);
8125        if (pi == null) {
8126            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8127            return;
8128        }
8129
8130        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8131            grantUri.prefix = true;
8132        }
8133        final UriPermission perm = findOrCreateUriPermissionLocked(
8134                pi.packageName, targetPkg, targetUid, grantUri);
8135        perm.grantModes(modeFlags, owner);
8136    }
8137
8138    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8139            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8140        if (targetPkg == null) {
8141            throw new NullPointerException("targetPkg");
8142        }
8143        int targetUid;
8144        final IPackageManager pm = AppGlobals.getPackageManager();
8145        try {
8146            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8147        } catch (RemoteException ex) {
8148            return;
8149        }
8150
8151        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8152                targetUid);
8153        if (targetUid < 0) {
8154            return;
8155        }
8156
8157        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8158                owner);
8159    }
8160
8161    static class NeededUriGrants extends ArrayList<GrantUri> {
8162        final String targetPkg;
8163        final int targetUid;
8164        final int flags;
8165
8166        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8167            this.targetPkg = targetPkg;
8168            this.targetUid = targetUid;
8169            this.flags = flags;
8170        }
8171    }
8172
8173    /**
8174     * Like checkGrantUriPermissionLocked, but takes an Intent.
8175     */
8176    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8177            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8178        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8179                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8180                + " clip=" + (intent != null ? intent.getClipData() : null)
8181                + " from " + intent + "; flags=0x"
8182                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8183
8184        if (targetPkg == null) {
8185            throw new NullPointerException("targetPkg");
8186        }
8187
8188        if (intent == null) {
8189            return null;
8190        }
8191        Uri data = intent.getData();
8192        ClipData clip = intent.getClipData();
8193        if (data == null && clip == null) {
8194            return null;
8195        }
8196        // Default userId for uris in the intent (if they don't specify it themselves)
8197        int contentUserHint = intent.getContentUserHint();
8198        if (contentUserHint == UserHandle.USER_CURRENT) {
8199            contentUserHint = UserHandle.getUserId(callingUid);
8200        }
8201        final IPackageManager pm = AppGlobals.getPackageManager();
8202        int targetUid;
8203        if (needed != null) {
8204            targetUid = needed.targetUid;
8205        } else {
8206            try {
8207                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8208                        targetUserId);
8209            } catch (RemoteException ex) {
8210                return null;
8211            }
8212            if (targetUid < 0) {
8213                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8214                        "Can't grant URI permission no uid for: " + targetPkg
8215                        + " on user " + targetUserId);
8216                return null;
8217            }
8218        }
8219        if (data != null) {
8220            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8221            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8222                    targetUid);
8223            if (targetUid > 0) {
8224                if (needed == null) {
8225                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8226                }
8227                needed.add(grantUri);
8228            }
8229        }
8230        if (clip != null) {
8231            for (int i=0; i<clip.getItemCount(); i++) {
8232                Uri uri = clip.getItemAt(i).getUri();
8233                if (uri != null) {
8234                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8235                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8236                            targetUid);
8237                    if (targetUid > 0) {
8238                        if (needed == null) {
8239                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8240                        }
8241                        needed.add(grantUri);
8242                    }
8243                } else {
8244                    Intent clipIntent = clip.getItemAt(i).getIntent();
8245                    if (clipIntent != null) {
8246                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8247                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8248                        if (newNeeded != null) {
8249                            needed = newNeeded;
8250                        }
8251                    }
8252                }
8253            }
8254        }
8255
8256        return needed;
8257    }
8258
8259    /**
8260     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8261     */
8262    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8263            UriPermissionOwner owner) {
8264        if (needed != null) {
8265            for (int i=0; i<needed.size(); i++) {
8266                GrantUri grantUri = needed.get(i);
8267                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8268                        grantUri, needed.flags, owner);
8269            }
8270        }
8271    }
8272
8273    void grantUriPermissionFromIntentLocked(int callingUid,
8274            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8275        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8276                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8277        if (needed == null) {
8278            return;
8279        }
8280
8281        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8282    }
8283
8284    /**
8285     * @param uri This uri must NOT contain an embedded userId.
8286     * @param userId The userId in which the uri is to be resolved.
8287     */
8288    @Override
8289    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8290            final int modeFlags, int userId) {
8291        enforceNotIsolatedCaller("grantUriPermission");
8292        GrantUri grantUri = new GrantUri(userId, uri, false);
8293        synchronized(this) {
8294            final ProcessRecord r = getRecordForAppLocked(caller);
8295            if (r == null) {
8296                throw new SecurityException("Unable to find app for caller "
8297                        + caller
8298                        + " when granting permission to uri " + grantUri);
8299            }
8300            if (targetPkg == null) {
8301                throw new IllegalArgumentException("null target");
8302            }
8303            if (grantUri == null) {
8304                throw new IllegalArgumentException("null uri");
8305            }
8306
8307            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8308                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8309                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8310                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8311
8312            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8313                    UserHandle.getUserId(r.uid));
8314        }
8315    }
8316
8317    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8318        if (perm.modeFlags == 0) {
8319            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8320                    perm.targetUid);
8321            if (perms != null) {
8322                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8323                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8324
8325                perms.remove(perm.uri);
8326                if (perms.isEmpty()) {
8327                    mGrantedUriPermissions.remove(perm.targetUid);
8328                }
8329            }
8330        }
8331    }
8332
8333    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8334        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8335                "Revoking all granted permissions to " + grantUri);
8336
8337        final IPackageManager pm = AppGlobals.getPackageManager();
8338        final String authority = grantUri.uri.getAuthority();
8339        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8340                MATCH_DEBUG_TRIAGED_MISSING);
8341        if (pi == null) {
8342            Slog.w(TAG, "No content provider found for permission revoke: "
8343                    + grantUri.toSafeString());
8344            return;
8345        }
8346
8347        // Does the caller have this permission on the URI?
8348        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8349            // If they don't have direct access to the URI, then revoke any
8350            // ownerless URI permissions that have been granted to them.
8351            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8352            if (perms != null) {
8353                boolean persistChanged = false;
8354                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8355                    final UriPermission perm = it.next();
8356                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8357                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8358                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8359                                "Revoking non-owned " + perm.targetUid
8360                                + " permission to " + perm.uri);
8361                        persistChanged |= perm.revokeModes(
8362                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8363                        if (perm.modeFlags == 0) {
8364                            it.remove();
8365                        }
8366                    }
8367                }
8368                if (perms.isEmpty()) {
8369                    mGrantedUriPermissions.remove(callingUid);
8370                }
8371                if (persistChanged) {
8372                    schedulePersistUriGrants();
8373                }
8374            }
8375            return;
8376        }
8377
8378        boolean persistChanged = false;
8379
8380        // Go through all of the permissions and remove any that match.
8381        int N = mGrantedUriPermissions.size();
8382        for (int i = 0; i < N; i++) {
8383            final int targetUid = mGrantedUriPermissions.keyAt(i);
8384            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8385
8386            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8387                final UriPermission perm = it.next();
8388                if (perm.uri.sourceUserId == grantUri.sourceUserId
8389                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8390                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8391                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8392                    persistChanged |= perm.revokeModes(
8393                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8394                    if (perm.modeFlags == 0) {
8395                        it.remove();
8396                    }
8397                }
8398            }
8399
8400            if (perms.isEmpty()) {
8401                mGrantedUriPermissions.remove(targetUid);
8402                N--;
8403                i--;
8404            }
8405        }
8406
8407        if (persistChanged) {
8408            schedulePersistUriGrants();
8409        }
8410    }
8411
8412    /**
8413     * @param uri This uri must NOT contain an embedded userId.
8414     * @param userId The userId in which the uri is to be resolved.
8415     */
8416    @Override
8417    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8418            int userId) {
8419        enforceNotIsolatedCaller("revokeUriPermission");
8420        synchronized(this) {
8421            final ProcessRecord r = getRecordForAppLocked(caller);
8422            if (r == null) {
8423                throw new SecurityException("Unable to find app for caller "
8424                        + caller
8425                        + " when revoking permission to uri " + uri);
8426            }
8427            if (uri == null) {
8428                Slog.w(TAG, "revokeUriPermission: null uri");
8429                return;
8430            }
8431
8432            if (!Intent.isAccessUriMode(modeFlags)) {
8433                return;
8434            }
8435
8436            final String authority = uri.getAuthority();
8437            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8438                    MATCH_DEBUG_TRIAGED_MISSING);
8439            if (pi == null) {
8440                Slog.w(TAG, "No content provider found for permission revoke: "
8441                        + uri.toSafeString());
8442                return;
8443            }
8444
8445            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8446        }
8447    }
8448
8449    /**
8450     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8451     * given package.
8452     *
8453     * @param packageName Package name to match, or {@code null} to apply to all
8454     *            packages.
8455     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8456     *            to all users.
8457     * @param persistable If persistable grants should be removed.
8458     */
8459    private void removeUriPermissionsForPackageLocked(
8460            String packageName, int userHandle, boolean persistable) {
8461        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8462            throw new IllegalArgumentException("Must narrow by either package or user");
8463        }
8464
8465        boolean persistChanged = false;
8466
8467        int N = mGrantedUriPermissions.size();
8468        for (int i = 0; i < N; i++) {
8469            final int targetUid = mGrantedUriPermissions.keyAt(i);
8470            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8471
8472            // Only inspect grants matching user
8473            if (userHandle == UserHandle.USER_ALL
8474                    || userHandle == UserHandle.getUserId(targetUid)) {
8475                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8476                    final UriPermission perm = it.next();
8477
8478                    // Only inspect grants matching package
8479                    if (packageName == null || perm.sourcePkg.equals(packageName)
8480                            || perm.targetPkg.equals(packageName)) {
8481                        persistChanged |= perm.revokeModes(persistable
8482                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8483
8484                        // Only remove when no modes remain; any persisted grants
8485                        // will keep this alive.
8486                        if (perm.modeFlags == 0) {
8487                            it.remove();
8488                        }
8489                    }
8490                }
8491
8492                if (perms.isEmpty()) {
8493                    mGrantedUriPermissions.remove(targetUid);
8494                    N--;
8495                    i--;
8496                }
8497            }
8498        }
8499
8500        if (persistChanged) {
8501            schedulePersistUriGrants();
8502        }
8503    }
8504
8505    @Override
8506    public IBinder newUriPermissionOwner(String name) {
8507        enforceNotIsolatedCaller("newUriPermissionOwner");
8508        synchronized(this) {
8509            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8510            return owner.getExternalTokenLocked();
8511        }
8512    }
8513
8514    @Override
8515    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8516        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8517        synchronized(this) {
8518            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8519            if (r == null) {
8520                throw new IllegalArgumentException("Activity does not exist; token="
8521                        + activityToken);
8522            }
8523            return r.getUriPermissionsLocked().getExternalTokenLocked();
8524        }
8525    }
8526    /**
8527     * @param uri This uri must NOT contain an embedded userId.
8528     * @param sourceUserId The userId in which the uri is to be resolved.
8529     * @param targetUserId The userId of the app that receives the grant.
8530     */
8531    @Override
8532    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8533            final int modeFlags, int sourceUserId, int targetUserId) {
8534        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8535                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8536                "grantUriPermissionFromOwner", null);
8537        synchronized(this) {
8538            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8539            if (owner == null) {
8540                throw new IllegalArgumentException("Unknown owner: " + token);
8541            }
8542            if (fromUid != Binder.getCallingUid()) {
8543                if (Binder.getCallingUid() != Process.myUid()) {
8544                    // Only system code can grant URI permissions on behalf
8545                    // of other users.
8546                    throw new SecurityException("nice try");
8547                }
8548            }
8549            if (targetPkg == null) {
8550                throw new IllegalArgumentException("null target");
8551            }
8552            if (uri == null) {
8553                throw new IllegalArgumentException("null uri");
8554            }
8555
8556            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8557                    modeFlags, owner, targetUserId);
8558        }
8559    }
8560
8561    /**
8562     * @param uri This uri must NOT contain an embedded userId.
8563     * @param userId The userId in which the uri is to be resolved.
8564     */
8565    @Override
8566    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8567        synchronized(this) {
8568            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8569            if (owner == null) {
8570                throw new IllegalArgumentException("Unknown owner: " + token);
8571            }
8572
8573            if (uri == null) {
8574                owner.removeUriPermissionsLocked(mode);
8575            } else {
8576                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8577            }
8578        }
8579    }
8580
8581    private void schedulePersistUriGrants() {
8582        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8583            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8584                    10 * DateUtils.SECOND_IN_MILLIS);
8585        }
8586    }
8587
8588    private void writeGrantedUriPermissions() {
8589        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8590
8591        // Snapshot permissions so we can persist without lock
8592        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8593        synchronized (this) {
8594            final int size = mGrantedUriPermissions.size();
8595            for (int i = 0; i < size; i++) {
8596                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8597                for (UriPermission perm : perms.values()) {
8598                    if (perm.persistedModeFlags != 0) {
8599                        persist.add(perm.snapshot());
8600                    }
8601                }
8602            }
8603        }
8604
8605        FileOutputStream fos = null;
8606        try {
8607            fos = mGrantFile.startWrite();
8608
8609            XmlSerializer out = new FastXmlSerializer();
8610            out.setOutput(fos, StandardCharsets.UTF_8.name());
8611            out.startDocument(null, true);
8612            out.startTag(null, TAG_URI_GRANTS);
8613            for (UriPermission.Snapshot perm : persist) {
8614                out.startTag(null, TAG_URI_GRANT);
8615                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8616                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8617                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8618                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8619                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8620                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8621                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8622                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8623                out.endTag(null, TAG_URI_GRANT);
8624            }
8625            out.endTag(null, TAG_URI_GRANTS);
8626            out.endDocument();
8627
8628            mGrantFile.finishWrite(fos);
8629        } catch (IOException e) {
8630            if (fos != null) {
8631                mGrantFile.failWrite(fos);
8632            }
8633        }
8634    }
8635
8636    private void readGrantedUriPermissionsLocked() {
8637        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8638
8639        final long now = System.currentTimeMillis();
8640
8641        FileInputStream fis = null;
8642        try {
8643            fis = mGrantFile.openRead();
8644            final XmlPullParser in = Xml.newPullParser();
8645            in.setInput(fis, StandardCharsets.UTF_8.name());
8646
8647            int type;
8648            while ((type = in.next()) != END_DOCUMENT) {
8649                final String tag = in.getName();
8650                if (type == START_TAG) {
8651                    if (TAG_URI_GRANT.equals(tag)) {
8652                        final int sourceUserId;
8653                        final int targetUserId;
8654                        final int userHandle = readIntAttribute(in,
8655                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8656                        if (userHandle != UserHandle.USER_NULL) {
8657                            // For backwards compatibility.
8658                            sourceUserId = userHandle;
8659                            targetUserId = userHandle;
8660                        } else {
8661                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8662                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8663                        }
8664                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8665                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8666                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8667                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8668                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8669                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8670
8671                        // Sanity check that provider still belongs to source package
8672                        // Both direct boot aware and unaware packages are fine as we
8673                        // will do filtering at query time to avoid multiple parsing.
8674                        final ProviderInfo pi = getProviderInfoLocked(
8675                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8676                                        | MATCH_DIRECT_BOOT_UNAWARE);
8677                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8678                            int targetUid = -1;
8679                            try {
8680                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8681                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8682                            } catch (RemoteException e) {
8683                            }
8684                            if (targetUid != -1) {
8685                                final UriPermission perm = findOrCreateUriPermissionLocked(
8686                                        sourcePkg, targetPkg, targetUid,
8687                                        new GrantUri(sourceUserId, uri, prefix));
8688                                perm.initPersistedModes(modeFlags, createdTime);
8689                            }
8690                        } else {
8691                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8692                                    + " but instead found " + pi);
8693                        }
8694                    }
8695                }
8696            }
8697        } catch (FileNotFoundException e) {
8698            // Missing grants is okay
8699        } catch (IOException e) {
8700            Slog.wtf(TAG, "Failed reading Uri grants", e);
8701        } catch (XmlPullParserException e) {
8702            Slog.wtf(TAG, "Failed reading Uri grants", e);
8703        } finally {
8704            IoUtils.closeQuietly(fis);
8705        }
8706    }
8707
8708    /**
8709     * @param uri This uri must NOT contain an embedded userId.
8710     * @param userId The userId in which the uri is to be resolved.
8711     */
8712    @Override
8713    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8714        enforceNotIsolatedCaller("takePersistableUriPermission");
8715
8716        Preconditions.checkFlagsArgument(modeFlags,
8717                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8718
8719        synchronized (this) {
8720            final int callingUid = Binder.getCallingUid();
8721            boolean persistChanged = false;
8722            GrantUri grantUri = new GrantUri(userId, uri, false);
8723
8724            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8725                    new GrantUri(userId, uri, false));
8726            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8727                    new GrantUri(userId, uri, true));
8728
8729            final boolean exactValid = (exactPerm != null)
8730                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8731            final boolean prefixValid = (prefixPerm != null)
8732                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8733
8734            if (!(exactValid || prefixValid)) {
8735                throw new SecurityException("No persistable permission grants found for UID "
8736                        + callingUid + " and Uri " + grantUri.toSafeString());
8737            }
8738
8739            if (exactValid) {
8740                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8741            }
8742            if (prefixValid) {
8743                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8744            }
8745
8746            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8747
8748            if (persistChanged) {
8749                schedulePersistUriGrants();
8750            }
8751        }
8752    }
8753
8754    /**
8755     * @param uri This uri must NOT contain an embedded userId.
8756     * @param userId The userId in which the uri is to be resolved.
8757     */
8758    @Override
8759    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8760        enforceNotIsolatedCaller("releasePersistableUriPermission");
8761
8762        Preconditions.checkFlagsArgument(modeFlags,
8763                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8764
8765        synchronized (this) {
8766            final int callingUid = Binder.getCallingUid();
8767            boolean persistChanged = false;
8768
8769            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8770                    new GrantUri(userId, uri, false));
8771            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8772                    new GrantUri(userId, uri, true));
8773            if (exactPerm == null && prefixPerm == null) {
8774                throw new SecurityException("No permission grants found for UID " + callingUid
8775                        + " and Uri " + uri.toSafeString());
8776            }
8777
8778            if (exactPerm != null) {
8779                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8780                removeUriPermissionIfNeededLocked(exactPerm);
8781            }
8782            if (prefixPerm != null) {
8783                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8784                removeUriPermissionIfNeededLocked(prefixPerm);
8785            }
8786
8787            if (persistChanged) {
8788                schedulePersistUriGrants();
8789            }
8790        }
8791    }
8792
8793    /**
8794     * Prune any older {@link UriPermission} for the given UID until outstanding
8795     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8796     *
8797     * @return if any mutations occured that require persisting.
8798     */
8799    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8800        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8801        if (perms == null) return false;
8802        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8803
8804        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8805        for (UriPermission perm : perms.values()) {
8806            if (perm.persistedModeFlags != 0) {
8807                persisted.add(perm);
8808            }
8809        }
8810
8811        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8812        if (trimCount <= 0) return false;
8813
8814        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8815        for (int i = 0; i < trimCount; i++) {
8816            final UriPermission perm = persisted.get(i);
8817
8818            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8819                    "Trimming grant created at " + perm.persistedCreateTime);
8820
8821            perm.releasePersistableModes(~0);
8822            removeUriPermissionIfNeededLocked(perm);
8823        }
8824
8825        return true;
8826    }
8827
8828    @Override
8829    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8830            String packageName, boolean incoming) {
8831        enforceNotIsolatedCaller("getPersistedUriPermissions");
8832        Preconditions.checkNotNull(packageName, "packageName");
8833
8834        final int callingUid = Binder.getCallingUid();
8835        final IPackageManager pm = AppGlobals.getPackageManager();
8836        try {
8837            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8838                    UserHandle.getUserId(callingUid));
8839            if (packageUid != callingUid) {
8840                throw new SecurityException(
8841                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8842            }
8843        } catch (RemoteException e) {
8844            throw new SecurityException("Failed to verify package name ownership");
8845        }
8846
8847        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8848        synchronized (this) {
8849            if (incoming) {
8850                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8851                        callingUid);
8852                if (perms == null) {
8853                    Slog.w(TAG, "No permission grants found for " + packageName);
8854                } else {
8855                    final int userId = UserHandle.getUserId(callingUid);
8856                    Set<String> existingAuthorities = null;
8857
8858                    for (UriPermission perm : perms.values()) {
8859                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8860                            // Is this provider available in the current boot state? If the user
8861                            // is not running and unlocked we check if the provider package exists.
8862                            if (!mUserController.isUserRunningLocked(userId,
8863                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8864                                String authority = perm.uri.uri.getAuthority();
8865                                if (existingAuthorities == null
8866                                        || !existingAuthorities.contains(authority)) {
8867                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8868                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8869                                    if (providerInfo != null) {
8870                                        if (existingAuthorities == null) {
8871                                            existingAuthorities = new ArraySet<>();
8872                                        }
8873                                        existingAuthorities.add(authority);
8874                                    } else {
8875                                        continue;
8876                                    }
8877                                }
8878                            }
8879                            result.add(perm.buildPersistedPublicApiObject());
8880                        }
8881                    }
8882                }
8883            } else {
8884                final int size = mGrantedUriPermissions.size();
8885                for (int i = 0; i < size; i++) {
8886                    final ArrayMap<GrantUri, UriPermission> perms =
8887                            mGrantedUriPermissions.valueAt(i);
8888                    for (UriPermission perm : perms.values()) {
8889                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8890                            result.add(perm.buildPersistedPublicApiObject());
8891                        }
8892                    }
8893                }
8894            }
8895        }
8896        return new ParceledListSlice<android.content.UriPermission>(result);
8897    }
8898
8899    @Override
8900    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8901            String packageName, int userId) {
8902        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8903                "getGrantedUriPermissions");
8904
8905        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8906        synchronized (this) {
8907            final int size = mGrantedUriPermissions.size();
8908            for (int i = 0; i < size; i++) {
8909                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8910                for (UriPermission perm : perms.values()) {
8911                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8912                            && perm.persistedModeFlags != 0) {
8913                        result.add(perm.buildPersistedPublicApiObject());
8914                    }
8915                }
8916            }
8917        }
8918        return new ParceledListSlice<android.content.UriPermission>(result);
8919    }
8920
8921    @Override
8922    public void clearGrantedUriPermissions(String packageName, int userId) {
8923        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8924                "clearGrantedUriPermissions");
8925        removeUriPermissionsForPackageLocked(packageName, userId, true);
8926    }
8927
8928    @Override
8929    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8930        synchronized (this) {
8931            ProcessRecord app =
8932                who != null ? getRecordForAppLocked(who) : null;
8933            if (app == null) return;
8934
8935            Message msg = Message.obtain();
8936            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8937            msg.obj = app;
8938            msg.arg1 = waiting ? 1 : 0;
8939            mUiHandler.sendMessage(msg);
8940        }
8941    }
8942
8943    @Override
8944    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8945        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8946        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8947        outInfo.availMem = Process.getFreeMemory();
8948        outInfo.totalMem = Process.getTotalMemory();
8949        outInfo.threshold = homeAppMem;
8950        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8951        outInfo.hiddenAppThreshold = cachedAppMem;
8952        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8953                ProcessList.SERVICE_ADJ);
8954        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8955                ProcessList.VISIBLE_APP_ADJ);
8956        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8957                ProcessList.FOREGROUND_APP_ADJ);
8958    }
8959
8960    // =========================================================
8961    // TASK MANAGEMENT
8962    // =========================================================
8963
8964    @Override
8965    public List<IAppTask> getAppTasks(String callingPackage) {
8966        int callingUid = Binder.getCallingUid();
8967        long ident = Binder.clearCallingIdentity();
8968
8969        synchronized(this) {
8970            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8971            try {
8972                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8973
8974                final int N = mRecentTasks.size();
8975                for (int i = 0; i < N; i++) {
8976                    TaskRecord tr = mRecentTasks.get(i);
8977                    // Skip tasks that do not match the caller.  We don't need to verify
8978                    // callingPackage, because we are also limiting to callingUid and know
8979                    // that will limit to the correct security sandbox.
8980                    if (tr.effectiveUid != callingUid) {
8981                        continue;
8982                    }
8983                    Intent intent = tr.getBaseIntent();
8984                    if (intent == null ||
8985                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8986                        continue;
8987                    }
8988                    ActivityManager.RecentTaskInfo taskInfo =
8989                            createRecentTaskInfoFromTaskRecord(tr);
8990                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8991                    list.add(taskImpl);
8992                }
8993            } finally {
8994                Binder.restoreCallingIdentity(ident);
8995            }
8996            return list;
8997        }
8998    }
8999
9000    @Override
9001    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9002        final int callingUid = Binder.getCallingUid();
9003        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9004
9005        synchronized(this) {
9006            if (DEBUG_ALL) Slog.v(
9007                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9008
9009            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9010                    callingUid);
9011
9012            // TODO: Improve with MRU list from all ActivityStacks.
9013            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9014        }
9015
9016        return list;
9017    }
9018
9019    /**
9020     * Creates a new RecentTaskInfo from a TaskRecord.
9021     */
9022    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9023        // Update the task description to reflect any changes in the task stack
9024        tr.updateTaskDescription();
9025
9026        // Compose the recent task info
9027        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9028        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9029        rti.persistentId = tr.taskId;
9030        rti.baseIntent = new Intent(tr.getBaseIntent());
9031        rti.origActivity = tr.origActivity;
9032        rti.realActivity = tr.realActivity;
9033        rti.description = tr.lastDescription;
9034        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9035        rti.userId = tr.userId;
9036        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9037        rti.firstActiveTime = tr.firstActiveTime;
9038        rti.lastActiveTime = tr.lastActiveTime;
9039        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9040        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9041        rti.numActivities = 0;
9042        if (tr.mBounds != null) {
9043            rti.bounds = new Rect(tr.mBounds);
9044        }
9045        rti.isDockable = tr.canGoInDockedStack();
9046        rti.resizeMode = tr.mResizeMode;
9047
9048        ActivityRecord base = null;
9049        ActivityRecord top = null;
9050        ActivityRecord tmp;
9051
9052        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9053            tmp = tr.mActivities.get(i);
9054            if (tmp.finishing) {
9055                continue;
9056            }
9057            base = tmp;
9058            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9059                top = base;
9060            }
9061            rti.numActivities++;
9062        }
9063
9064        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9065        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9066
9067        return rti;
9068    }
9069
9070    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9071        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9072                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9073        if (!allowed) {
9074            if (checkPermission(android.Manifest.permission.GET_TASKS,
9075                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9076                // Temporary compatibility: some existing apps on the system image may
9077                // still be requesting the old permission and not switched to the new
9078                // one; if so, we'll still allow them full access.  This means we need
9079                // to see if they are holding the old permission and are a system app.
9080                try {
9081                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9082                        allowed = true;
9083                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9084                                + " is using old GET_TASKS but privileged; allowing");
9085                    }
9086                } catch (RemoteException e) {
9087                }
9088            }
9089        }
9090        if (!allowed) {
9091            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9092                    + " does not hold REAL_GET_TASKS; limiting output");
9093        }
9094        return allowed;
9095    }
9096
9097    @Override
9098    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9099        final int callingUid = Binder.getCallingUid();
9100        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9101                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9102
9103        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9104        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9105        synchronized (this) {
9106            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9107                    callingUid);
9108            final boolean detailed = checkCallingPermission(
9109                    android.Manifest.permission.GET_DETAILED_TASKS)
9110                    == PackageManager.PERMISSION_GRANTED;
9111
9112            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9113                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9114                return Collections.emptyList();
9115            }
9116            mRecentTasks.loadUserRecentsLocked(userId);
9117
9118            final int recentsCount = mRecentTasks.size();
9119            ArrayList<ActivityManager.RecentTaskInfo> res =
9120                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9121
9122            final Set<Integer> includedUsers;
9123            if (includeProfiles) {
9124                includedUsers = mUserController.getProfileIds(userId);
9125            } else {
9126                includedUsers = new HashSet<>();
9127            }
9128            includedUsers.add(Integer.valueOf(userId));
9129
9130            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9131                TaskRecord tr = mRecentTasks.get(i);
9132                // Only add calling user or related users recent tasks
9133                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9134                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9135                    continue;
9136                }
9137
9138                if (tr.realActivitySuspended) {
9139                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9140                    continue;
9141                }
9142
9143                // Return the entry if desired by the caller.  We always return
9144                // the first entry, because callers always expect this to be the
9145                // foreground app.  We may filter others if the caller has
9146                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9147                // we should exclude the entry.
9148
9149                if (i == 0
9150                        || withExcluded
9151                        || (tr.intent == null)
9152                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9153                                == 0)) {
9154                    if (!allowed) {
9155                        // If the caller doesn't have the GET_TASKS permission, then only
9156                        // allow them to see a small subset of tasks -- their own and home.
9157                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9158                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9159                            continue;
9160                        }
9161                    }
9162                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9163                        if (tr.stack != null && tr.stack.isHomeStack()) {
9164                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9165                                    "Skipping, home stack task: " + tr);
9166                            continue;
9167                        }
9168                    }
9169                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9170                        final ActivityStack stack = tr.stack;
9171                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9172                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9173                                    "Skipping, top task in docked stack: " + tr);
9174                            continue;
9175                        }
9176                    }
9177                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9178                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9179                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9180                                    "Skipping, pinned stack task: " + tr);
9181                            continue;
9182                        }
9183                    }
9184                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9185                        // Don't include auto remove tasks that are finished or finishing.
9186                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9187                                "Skipping, auto-remove without activity: " + tr);
9188                        continue;
9189                    }
9190                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9191                            && !tr.isAvailable) {
9192                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9193                                "Skipping, unavail real act: " + tr);
9194                        continue;
9195                    }
9196
9197                    if (!tr.mUserSetupComplete) {
9198                        // Don't include task launched while user is not done setting-up.
9199                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9200                                "Skipping, user setup not complete: " + tr);
9201                        continue;
9202                    }
9203
9204                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9205                    if (!detailed) {
9206                        rti.baseIntent.replaceExtras((Bundle)null);
9207                    }
9208
9209                    res.add(rti);
9210                    maxNum--;
9211                }
9212            }
9213            return res;
9214        }
9215    }
9216
9217    @Override
9218    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9219        synchronized (this) {
9220            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9221                    "getTaskThumbnail()");
9222            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9223                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9224            if (tr != null) {
9225                return tr.getTaskThumbnailLocked();
9226            }
9227        }
9228        return null;
9229    }
9230
9231    @Override
9232    public int addAppTask(IBinder activityToken, Intent intent,
9233            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9234        final int callingUid = Binder.getCallingUid();
9235        final long callingIdent = Binder.clearCallingIdentity();
9236
9237        try {
9238            synchronized (this) {
9239                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9240                if (r == null) {
9241                    throw new IllegalArgumentException("Activity does not exist; token="
9242                            + activityToken);
9243                }
9244                ComponentName comp = intent.getComponent();
9245                if (comp == null) {
9246                    throw new IllegalArgumentException("Intent " + intent
9247                            + " must specify explicit component");
9248                }
9249                if (thumbnail.getWidth() != mThumbnailWidth
9250                        || thumbnail.getHeight() != mThumbnailHeight) {
9251                    throw new IllegalArgumentException("Bad thumbnail size: got "
9252                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9253                            + mThumbnailWidth + "x" + mThumbnailHeight);
9254                }
9255                if (intent.getSelector() != null) {
9256                    intent.setSelector(null);
9257                }
9258                if (intent.getSourceBounds() != null) {
9259                    intent.setSourceBounds(null);
9260                }
9261                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9262                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9263                        // The caller has added this as an auto-remove task...  that makes no
9264                        // sense, so turn off auto-remove.
9265                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9266                    }
9267                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9268                    // Must be a new task.
9269                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9270                }
9271                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9272                    mLastAddedTaskActivity = null;
9273                }
9274                ActivityInfo ainfo = mLastAddedTaskActivity;
9275                if (ainfo == null) {
9276                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9277                            comp, 0, UserHandle.getUserId(callingUid));
9278                    if (ainfo.applicationInfo.uid != callingUid) {
9279                        throw new SecurityException(
9280                                "Can't add task for another application: target uid="
9281                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9282                    }
9283                }
9284
9285                // Use the full screen as the context for the task thumbnail
9286                final Point displaySize = new Point();
9287                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9288                r.task.stack.getDisplaySize(displaySize);
9289                thumbnailInfo.taskWidth = displaySize.x;
9290                thumbnailInfo.taskHeight = displaySize.y;
9291                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9292
9293                TaskRecord task = new TaskRecord(this,
9294                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9295                        ainfo, intent, description, thumbnailInfo);
9296
9297                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9298                if (trimIdx >= 0) {
9299                    // If this would have caused a trim, then we'll abort because that
9300                    // means it would be added at the end of the list but then just removed.
9301                    return INVALID_TASK_ID;
9302                }
9303
9304                final int N = mRecentTasks.size();
9305                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9306                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9307                    tr.removedFromRecents();
9308                }
9309
9310                task.inRecents = true;
9311                mRecentTasks.add(task);
9312                r.task.stack.addTask(task, false, "addAppTask");
9313
9314                task.setLastThumbnailLocked(thumbnail);
9315                task.freeLastThumbnail();
9316
9317                return task.taskId;
9318            }
9319        } finally {
9320            Binder.restoreCallingIdentity(callingIdent);
9321        }
9322    }
9323
9324    @Override
9325    public Point getAppTaskThumbnailSize() {
9326        synchronized (this) {
9327            return new Point(mThumbnailWidth,  mThumbnailHeight);
9328        }
9329    }
9330
9331    @Override
9332    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9333        synchronized (this) {
9334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9335            if (r != null) {
9336                r.setTaskDescription(td);
9337                r.task.updateTaskDescription();
9338            }
9339        }
9340    }
9341
9342    @Override
9343    public void setTaskResizeable(int taskId, int resizeableMode) {
9344        synchronized (this) {
9345            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9346                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9347            if (task == null) {
9348                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9349                return;
9350            }
9351            if (task.mResizeMode != resizeableMode) {
9352                task.mResizeMode = resizeableMode;
9353                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9354                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9355                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9356            }
9357        }
9358    }
9359
9360    @Override
9361    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9362        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9363        long ident = Binder.clearCallingIdentity();
9364        try {
9365            synchronized (this) {
9366                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9367                if (task == null) {
9368                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9369                    return;
9370                }
9371                int stackId = task.stack.mStackId;
9372                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9373                // in crop windows resize mode or if the task size is affected by the docked stack
9374                // changing size. No need to update configuration.
9375                if (bounds != null && task.inCropWindowsResizeMode()
9376                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9377                    mWindowManager.scrollTask(task.taskId, bounds);
9378                    return;
9379                }
9380
9381                // Place the task in the right stack if it isn't there already based on
9382                // the requested bounds.
9383                // The stack transition logic is:
9384                // - a null bounds on a freeform task moves that task to fullscreen
9385                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9386                //   that task to freeform
9387                // - otherwise the task is not moved
9388                if (!StackId.isTaskResizeAllowed(stackId)) {
9389                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9390                }
9391                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9392                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9393                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9394                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9395                }
9396                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9397                if (stackId != task.stack.mStackId) {
9398                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9399                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9400                    preserveWindow = false;
9401                }
9402
9403                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9404                        false /* deferResume */);
9405            }
9406        } finally {
9407            Binder.restoreCallingIdentity(ident);
9408        }
9409    }
9410
9411    @Override
9412    public Rect getTaskBounds(int taskId) {
9413        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9414        long ident = Binder.clearCallingIdentity();
9415        Rect rect = new Rect();
9416        try {
9417            synchronized (this) {
9418                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9419                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9420                if (task == null) {
9421                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9422                    return rect;
9423                }
9424                if (task.stack != null) {
9425                    // Return the bounds from window manager since it will be adjusted for various
9426                    // things like the presense of a docked stack for tasks that aren't resizeable.
9427                    mWindowManager.getTaskBounds(task.taskId, rect);
9428                } else {
9429                    // Task isn't in window manager yet since it isn't associated with a stack.
9430                    // Return the persist value from activity manager
9431                    if (task.mBounds != null) {
9432                        rect.set(task.mBounds);
9433                    } else if (task.mLastNonFullscreenBounds != null) {
9434                        rect.set(task.mLastNonFullscreenBounds);
9435                    }
9436                }
9437            }
9438        } finally {
9439            Binder.restoreCallingIdentity(ident);
9440        }
9441        return rect;
9442    }
9443
9444    @Override
9445    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9446        if (userId != UserHandle.getCallingUserId()) {
9447            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9448                    "getTaskDescriptionIcon");
9449        }
9450        final File passedIconFile = new File(filePath);
9451        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9452                passedIconFile.getName());
9453        if (!legitIconFile.getPath().equals(filePath)
9454                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9455            throw new IllegalArgumentException("Bad file path: " + filePath
9456                    + " passed for userId " + userId);
9457        }
9458        return mRecentTasks.getTaskDescriptionIcon(filePath);
9459    }
9460
9461    @Override
9462    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9463            throws RemoteException {
9464        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9465                opts.getCustomInPlaceResId() == 0) {
9466            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9467                    "with valid animation");
9468        }
9469        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9470        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9471                opts.getCustomInPlaceResId());
9472        mWindowManager.executeAppTransition();
9473    }
9474
9475    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9476            boolean removeFromRecents) {
9477        if (removeFromRecents) {
9478            mRecentTasks.remove(tr);
9479            tr.removedFromRecents();
9480        }
9481        ComponentName component = tr.getBaseIntent().getComponent();
9482        if (component == null) {
9483            Slog.w(TAG, "No component for base intent of task: " + tr);
9484            return;
9485        }
9486
9487        // Find any running services associated with this app and stop if needed.
9488        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9489
9490        if (!killProcess) {
9491            return;
9492        }
9493
9494        // Determine if the process(es) for this task should be killed.
9495        final String pkg = component.getPackageName();
9496        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9497        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9498        for (int i = 0; i < pmap.size(); i++) {
9499
9500            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9501            for (int j = 0; j < uids.size(); j++) {
9502                ProcessRecord proc = uids.valueAt(j);
9503                if (proc.userId != tr.userId) {
9504                    // Don't kill process for a different user.
9505                    continue;
9506                }
9507                if (proc == mHomeProcess) {
9508                    // Don't kill the home process along with tasks from the same package.
9509                    continue;
9510                }
9511                if (!proc.pkgList.containsKey(pkg)) {
9512                    // Don't kill process that is not associated with this task.
9513                    continue;
9514                }
9515
9516                for (int k = 0; k < proc.activities.size(); k++) {
9517                    TaskRecord otherTask = proc.activities.get(k).task;
9518                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9519                        // Don't kill process(es) that has an activity in a different task that is
9520                        // also in recents.
9521                        return;
9522                    }
9523                }
9524
9525                if (proc.foregroundServices) {
9526                    // Don't kill process(es) with foreground service.
9527                    return;
9528                }
9529
9530                // Add process to kill list.
9531                procsToKill.add(proc);
9532            }
9533        }
9534
9535        // Kill the running processes.
9536        for (int i = 0; i < procsToKill.size(); i++) {
9537            ProcessRecord pr = procsToKill.get(i);
9538            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9539                    && pr.curReceiver == null) {
9540                pr.kill("remove task", true);
9541            } else {
9542                // We delay killing processes that are not in the background or running a receiver.
9543                pr.waitingToKill = "remove task";
9544            }
9545        }
9546    }
9547
9548    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9549        // Remove all tasks with activities in the specified package from the list of recent tasks
9550        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9551            TaskRecord tr = mRecentTasks.get(i);
9552            if (tr.userId != userId) continue;
9553
9554            ComponentName cn = tr.intent.getComponent();
9555            if (cn != null && cn.getPackageName().equals(packageName)) {
9556                // If the package name matches, remove the task.
9557                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9558            }
9559        }
9560    }
9561
9562    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9563            int userId) {
9564
9565        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9566            TaskRecord tr = mRecentTasks.get(i);
9567            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9568                continue;
9569            }
9570
9571            ComponentName cn = tr.intent.getComponent();
9572            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9573                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9574            if (sameComponent) {
9575                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9576            }
9577        }
9578    }
9579
9580    /**
9581     * Removes the task with the specified task id.
9582     *
9583     * @param taskId Identifier of the task to be removed.
9584     * @param killProcess Kill any process associated with the task if possible.
9585     * @param removeFromRecents Whether to also remove the task from recents.
9586     * @return Returns true if the given task was found and removed.
9587     */
9588    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9589            boolean removeFromRecents) {
9590        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9591                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9592        if (tr != null) {
9593            tr.removeTaskActivitiesLocked();
9594            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9595            if (tr.isPersistable) {
9596                notifyTaskPersisterLocked(null, true);
9597            }
9598            return true;
9599        }
9600        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9601        return false;
9602    }
9603
9604    @Override
9605    public void removeStack(int stackId) {
9606        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9607        if (stackId == HOME_STACK_ID) {
9608            throw new IllegalArgumentException("Removing home stack is not allowed.");
9609        }
9610
9611        synchronized (this) {
9612            final long ident = Binder.clearCallingIdentity();
9613            try {
9614                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9615                if (stack == null) {
9616                    return;
9617                }
9618                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9619                for (int i = tasks.size() - 1; i >= 0; i--) {
9620                    removeTaskByIdLocked(
9621                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9622                }
9623            } finally {
9624                Binder.restoreCallingIdentity(ident);
9625            }
9626        }
9627    }
9628
9629    @Override
9630    public boolean removeTask(int taskId) {
9631        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9632        synchronized (this) {
9633            final long ident = Binder.clearCallingIdentity();
9634            try {
9635                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9636            } finally {
9637                Binder.restoreCallingIdentity(ident);
9638            }
9639        }
9640    }
9641
9642    /**
9643     * TODO: Add mController hook
9644     */
9645    @Override
9646    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9647        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9648
9649        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9650        synchronized(this) {
9651            moveTaskToFrontLocked(taskId, flags, bOptions);
9652        }
9653    }
9654
9655    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9656        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9657
9658        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9659                Binder.getCallingUid(), -1, -1, "Task to front")) {
9660            ActivityOptions.abort(options);
9661            return;
9662        }
9663        final long origId = Binder.clearCallingIdentity();
9664        try {
9665            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9666            if (task == null) {
9667                Slog.d(TAG, "Could not find task for id: "+ taskId);
9668                return;
9669            }
9670            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9671                mStackSupervisor.showLockTaskToast();
9672                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9673                return;
9674            }
9675            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9676            if (prev != null && prev.isRecentsActivity()) {
9677                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9678            }
9679            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9680                    false /* forceNonResizable */);
9681        } finally {
9682            Binder.restoreCallingIdentity(origId);
9683        }
9684        ActivityOptions.abort(options);
9685    }
9686
9687    /**
9688     * Moves an activity, and all of the other activities within the same task, to the bottom
9689     * of the history stack.  The activity's order within the task is unchanged.
9690     *
9691     * @param token A reference to the activity we wish to move
9692     * @param nonRoot If false then this only works if the activity is the root
9693     *                of a task; if true it will work for any activity in a task.
9694     * @return Returns true if the move completed, false if not.
9695     */
9696    @Override
9697    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9698        enforceNotIsolatedCaller("moveActivityTaskToBack");
9699        synchronized(this) {
9700            final long origId = Binder.clearCallingIdentity();
9701            try {
9702                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9703                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9704                if (task != null) {
9705                    if (mStackSupervisor.isLockedTask(task)) {
9706                        mStackSupervisor.showLockTaskToast();
9707                        return false;
9708                    }
9709                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9710                }
9711            } finally {
9712                Binder.restoreCallingIdentity(origId);
9713            }
9714        }
9715        return false;
9716    }
9717
9718    @Override
9719    public void moveTaskBackwards(int task) {
9720        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9721                "moveTaskBackwards()");
9722
9723        synchronized(this) {
9724            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9725                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9726                return;
9727            }
9728            final long origId = Binder.clearCallingIdentity();
9729            moveTaskBackwardsLocked(task);
9730            Binder.restoreCallingIdentity(origId);
9731        }
9732    }
9733
9734    private final void moveTaskBackwardsLocked(int task) {
9735        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9736    }
9737
9738    @Override
9739    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9740            IActivityContainerCallback callback) throws RemoteException {
9741        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9742        synchronized (this) {
9743            if (parentActivityToken == null) {
9744                throw new IllegalArgumentException("parent token must not be null");
9745            }
9746            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9747            if (r == null) {
9748                return null;
9749            }
9750            if (callback == null) {
9751                throw new IllegalArgumentException("callback must not be null");
9752            }
9753            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9754        }
9755    }
9756
9757    @Override
9758    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9759        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9760        synchronized (this) {
9761            mStackSupervisor.deleteActivityContainer(container);
9762        }
9763    }
9764
9765    @Override
9766    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9767        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9768        synchronized (this) {
9769            final int stackId = mStackSupervisor.getNextStackId();
9770            final ActivityStack stack =
9771                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9772            if (stack == null) {
9773                return null;
9774            }
9775            return stack.mActivityContainer;
9776        }
9777    }
9778
9779    @Override
9780    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9781        synchronized (this) {
9782            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9783            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9784                return stack.mActivityContainer.getDisplayId();
9785            }
9786            return Display.DEFAULT_DISPLAY;
9787        }
9788    }
9789
9790    @Override
9791    public int getActivityStackId(IBinder token) throws RemoteException {
9792        synchronized (this) {
9793            ActivityStack stack = ActivityRecord.getStackLocked(token);
9794            if (stack == null) {
9795                return INVALID_STACK_ID;
9796            }
9797            return stack.mStackId;
9798        }
9799    }
9800
9801    @Override
9802    public void exitFreeformMode(IBinder token) throws RemoteException {
9803        synchronized (this) {
9804            long ident = Binder.clearCallingIdentity();
9805            try {
9806                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9807                if (r == null) {
9808                    throw new IllegalArgumentException(
9809                            "exitFreeformMode: No activity record matching token=" + token);
9810                }
9811                final ActivityStack stack = r.getStackLocked(token);
9812                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9813                    throw new IllegalStateException(
9814                            "exitFreeformMode: You can only go fullscreen from freeform.");
9815                }
9816                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9817                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9818                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9819            } finally {
9820                Binder.restoreCallingIdentity(ident);
9821            }
9822        }
9823    }
9824
9825    @Override
9826    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9827        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9828        if (stackId == HOME_STACK_ID) {
9829            throw new IllegalArgumentException(
9830                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9831        }
9832        synchronized (this) {
9833            long ident = Binder.clearCallingIdentity();
9834            try {
9835                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9836                        + " to stackId=" + stackId + " toTop=" + toTop);
9837                if (stackId == DOCKED_STACK_ID) {
9838                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9839                            null /* initialBounds */);
9840                }
9841                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9842                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9843                if (result && stackId == DOCKED_STACK_ID) {
9844                    // If task moved to docked stack - show recents if needed.
9845                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9846                            "moveTaskToDockedStack");
9847                }
9848            } finally {
9849                Binder.restoreCallingIdentity(ident);
9850            }
9851        }
9852    }
9853
9854    @Override
9855    public void swapDockedAndFullscreenStack() throws RemoteException {
9856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9857        synchronized (this) {
9858            long ident = Binder.clearCallingIdentity();
9859            try {
9860                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9861                        FULLSCREEN_WORKSPACE_STACK_ID);
9862                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9863                        : null;
9864                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9865                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9866                        : null;
9867                if (topTask == null || tasks == null || tasks.size() == 0) {
9868                    Slog.w(TAG,
9869                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9870                    return;
9871                }
9872
9873                // TODO: App transition
9874                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9875
9876                // Defer the resume so resume/pausing while moving stacks is dangerous.
9877                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9878                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9879                        ANIMATE, true /* deferResume */);
9880                final int size = tasks.size();
9881                for (int i = 0; i < size; i++) {
9882                    final int id = tasks.get(i).taskId;
9883                    if (id == topTask.taskId) {
9884                        continue;
9885                    }
9886                    mStackSupervisor.moveTaskToStackLocked(id,
9887                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9888                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9889                }
9890
9891                // Because we deferred the resume, to avoid conflicts with stack switches while
9892                // resuming, we need to do it after all the tasks are moved.
9893                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9894                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9895
9896                mWindowManager.executeAppTransition();
9897            } finally {
9898                Binder.restoreCallingIdentity(ident);
9899            }
9900        }
9901    }
9902
9903    /**
9904     * Moves the input task to the docked stack.
9905     *
9906     * @param taskId Id of task to move.
9907     * @param createMode The mode the docked stack should be created in if it doesn't exist
9908     *                   already. See
9909     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9910     *                   and
9911     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9912     * @param toTop If the task and stack should be moved to the top.
9913     * @param animate Whether we should play an animation for the moving the task
9914     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9915     *                      docked stack. Pass {@code null} to use default bounds.
9916     */
9917    @Override
9918    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9919            Rect initialBounds, boolean moveHomeStackFront) {
9920        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9921        synchronized (this) {
9922            long ident = Binder.clearCallingIdentity();
9923            try {
9924                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9925                        + " to createMode=" + createMode + " toTop=" + toTop);
9926                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9927                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9928                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9929                        animate, DEFER_RESUME);
9930                if (moved) {
9931                    if (moveHomeStackFront) {
9932                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9933                    }
9934                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9935                }
9936                return moved;
9937            } finally {
9938                Binder.restoreCallingIdentity(ident);
9939            }
9940        }
9941    }
9942
9943    /**
9944     * Moves the top activity in the input stackId to the pinned stack.
9945     *
9946     * @param stackId Id of stack to move the top activity to pinned stack.
9947     * @param bounds Bounds to use for pinned stack.
9948     *
9949     * @return True if the top activity of the input stack was successfully moved to the pinned
9950     *          stack.
9951     */
9952    @Override
9953    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9954        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9955        synchronized (this) {
9956            if (!mSupportsPictureInPicture) {
9957                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9958                        + "Device doesn't support picture-in-pciture mode");
9959            }
9960
9961            long ident = Binder.clearCallingIdentity();
9962            try {
9963                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9964            } finally {
9965                Binder.restoreCallingIdentity(ident);
9966            }
9967        }
9968    }
9969
9970    @Override
9971    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9972            boolean preserveWindows, boolean animate, int animationDuration) {
9973        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9974        long ident = Binder.clearCallingIdentity();
9975        try {
9976            synchronized (this) {
9977                if (animate) {
9978                    if (stackId == PINNED_STACK_ID) {
9979                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9980                    } else {
9981                        throw new IllegalArgumentException("Stack: " + stackId
9982                                + " doesn't support animated resize.");
9983                    }
9984                } else {
9985                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9986                            null /* tempTaskInsetBounds */, preserveWindows,
9987                            allowResizeInDockedMode, !DEFER_RESUME);
9988                }
9989            }
9990        } finally {
9991            Binder.restoreCallingIdentity(ident);
9992        }
9993    }
9994
9995    @Override
9996    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9997            Rect tempDockedTaskInsetBounds,
9998            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9999        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10000                "resizeDockedStack()");
10001        long ident = Binder.clearCallingIdentity();
10002        try {
10003            synchronized (this) {
10004                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10005                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10006                        PRESERVE_WINDOWS);
10007            }
10008        } finally {
10009            Binder.restoreCallingIdentity(ident);
10010        }
10011    }
10012
10013    @Override
10014    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10015        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10016                "resizePinnedStack()");
10017        final long ident = Binder.clearCallingIdentity();
10018        try {
10019            synchronized (this) {
10020                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10021            }
10022        } finally {
10023            Binder.restoreCallingIdentity(ident);
10024        }
10025    }
10026
10027    @Override
10028    public void positionTaskInStack(int taskId, int stackId, int position) {
10029        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10030        if (stackId == HOME_STACK_ID) {
10031            throw new IllegalArgumentException(
10032                    "positionTaskInStack: Attempt to change the position of task "
10033                    + taskId + " in/to home stack");
10034        }
10035        synchronized (this) {
10036            long ident = Binder.clearCallingIdentity();
10037            try {
10038                if (DEBUG_STACK) Slog.d(TAG_STACK,
10039                        "positionTaskInStack: positioning task=" + taskId
10040                        + " in stackId=" + stackId + " at position=" + position);
10041                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10042            } finally {
10043                Binder.restoreCallingIdentity(ident);
10044            }
10045        }
10046    }
10047
10048    @Override
10049    public List<StackInfo> getAllStackInfos() {
10050        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10051        long ident = Binder.clearCallingIdentity();
10052        try {
10053            synchronized (this) {
10054                return mStackSupervisor.getAllStackInfosLocked();
10055            }
10056        } finally {
10057            Binder.restoreCallingIdentity(ident);
10058        }
10059    }
10060
10061    @Override
10062    public StackInfo getStackInfo(int stackId) {
10063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                return mStackSupervisor.getStackInfoLocked(stackId);
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(ident);
10071        }
10072    }
10073
10074    @Override
10075    public boolean isInHomeStack(int taskId) {
10076        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10077        long ident = Binder.clearCallingIdentity();
10078        try {
10079            synchronized (this) {
10080                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10081                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10082                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10083            }
10084        } finally {
10085            Binder.restoreCallingIdentity(ident);
10086        }
10087    }
10088
10089    @Override
10090    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10091        synchronized(this) {
10092            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10093        }
10094    }
10095
10096    @Override
10097    public void updateDeviceOwner(String packageName) {
10098        final int callingUid = Binder.getCallingUid();
10099        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10100            throw new SecurityException("updateDeviceOwner called from non-system process");
10101        }
10102        synchronized (this) {
10103            mDeviceOwnerName = packageName;
10104        }
10105    }
10106
10107    @Override
10108    public void updateLockTaskPackages(int userId, String[] packages) {
10109        final int callingUid = Binder.getCallingUid();
10110        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10111            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10112                    "updateLockTaskPackages()");
10113        }
10114        synchronized (this) {
10115            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10116                    Arrays.toString(packages));
10117            mLockTaskPackages.put(userId, packages);
10118            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10119        }
10120    }
10121
10122
10123    void startLockTaskModeLocked(TaskRecord task) {
10124        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10125        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10126            return;
10127        }
10128
10129        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10130        // is initiated by system after the pinning request was shown and locked mode is initiated
10131        // by an authorized app directly
10132        final int callingUid = Binder.getCallingUid();
10133        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10134        long ident = Binder.clearCallingIdentity();
10135        try {
10136            if (!isSystemInitiated) {
10137                task.mLockTaskUid = callingUid;
10138                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10139                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10140                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10141                    StatusBarManagerInternal statusBarManager =
10142                            LocalServices.getService(StatusBarManagerInternal.class);
10143                    if (statusBarManager != null) {
10144                        statusBarManager.showScreenPinningRequest(task.taskId);
10145                    }
10146                    return;
10147                }
10148
10149                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10150                if (stack == null || task != stack.topTask()) {
10151                    throw new IllegalArgumentException("Invalid task, not in foreground");
10152                }
10153            }
10154            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10155                    "Locking fully");
10156            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10157                    ActivityManager.LOCK_TASK_MODE_PINNED :
10158                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10159                    "startLockTask", true);
10160        } finally {
10161            Binder.restoreCallingIdentity(ident);
10162        }
10163    }
10164
10165    @Override
10166    public void startLockTaskMode(int taskId) {
10167        synchronized (this) {
10168            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10169            if (task != null) {
10170                startLockTaskModeLocked(task);
10171            }
10172        }
10173    }
10174
10175    @Override
10176    public void startLockTaskMode(IBinder token) {
10177        synchronized (this) {
10178            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10179            if (r == null) {
10180                return;
10181            }
10182            final TaskRecord task = r.task;
10183            if (task != null) {
10184                startLockTaskModeLocked(task);
10185            }
10186        }
10187    }
10188
10189    @Override
10190    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10191        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10192        // This makes inner call to look as if it was initiated by system.
10193        long ident = Binder.clearCallingIdentity();
10194        try {
10195            synchronized (this) {
10196                startLockTaskMode(taskId);
10197            }
10198        } finally {
10199            Binder.restoreCallingIdentity(ident);
10200        }
10201    }
10202
10203    @Override
10204    public void stopLockTaskMode() {
10205        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10206        if (lockTask == null) {
10207            // Our work here is done.
10208            return;
10209        }
10210
10211        final int callingUid = Binder.getCallingUid();
10212        final int lockTaskUid = lockTask.mLockTaskUid;
10213        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10214        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10215            // Done.
10216            return;
10217        } else {
10218            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10219            // It is possible lockTaskMode was started by the system process because
10220            // android:lockTaskMode is set to a locking value in the application manifest
10221            // instead of the app calling startLockTaskMode. In this case
10222            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10223            // {@link TaskRecord.effectiveUid} instead. Also caller with
10224            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10225            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10226                    && callingUid != lockTaskUid
10227                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10228                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10229                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10230            }
10231        }
10232        long ident = Binder.clearCallingIdentity();
10233        try {
10234            Log.d(TAG, "stopLockTaskMode");
10235            // Stop lock task
10236            synchronized (this) {
10237                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10238                        "stopLockTask", true);
10239            }
10240            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10241            if (tm != null) {
10242                tm.showInCallScreen(false);
10243            }
10244        } finally {
10245            Binder.restoreCallingIdentity(ident);
10246        }
10247    }
10248
10249    /**
10250     * This API should be called by SystemUI only when user perform certain action to dismiss
10251     * lock task mode. We should only dismiss pinned lock task mode in this case.
10252     */
10253    @Override
10254    public void stopSystemLockTaskMode() throws RemoteException {
10255        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10256            stopLockTaskMode();
10257        } else {
10258            mStackSupervisor.showLockTaskToast();
10259        }
10260    }
10261
10262    @Override
10263    public boolean isInLockTaskMode() {
10264        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10265    }
10266
10267    @Override
10268    public int getLockTaskModeState() {
10269        synchronized (this) {
10270            return mStackSupervisor.getLockTaskModeState();
10271        }
10272    }
10273
10274    @Override
10275    public void showLockTaskEscapeMessage(IBinder token) {
10276        synchronized (this) {
10277            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10278            if (r == null) {
10279                return;
10280            }
10281            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10282        }
10283    }
10284
10285    // =========================================================
10286    // CONTENT PROVIDERS
10287    // =========================================================
10288
10289    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10290        List<ProviderInfo> providers = null;
10291        try {
10292            providers = AppGlobals.getPackageManager()
10293                    .queryContentProviders(app.processName, app.uid,
10294                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10295                                    | MATCH_DEBUG_TRIAGED_MISSING)
10296                    .getList();
10297        } catch (RemoteException ex) {
10298        }
10299        if (DEBUG_MU) Slog.v(TAG_MU,
10300                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10301        int userId = app.userId;
10302        if (providers != null) {
10303            int N = providers.size();
10304            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10305            for (int i=0; i<N; i++) {
10306                // TODO: keep logic in sync with installEncryptionUnawareProviders
10307                ProviderInfo cpi =
10308                    (ProviderInfo)providers.get(i);
10309                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10310                        cpi.name, cpi.flags);
10311                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10312                    // This is a singleton provider, but a user besides the
10313                    // default user is asking to initialize a process it runs
10314                    // in...  well, no, it doesn't actually run in this process,
10315                    // it runs in the process of the default user.  Get rid of it.
10316                    providers.remove(i);
10317                    N--;
10318                    i--;
10319                    continue;
10320                }
10321
10322                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10323                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10324                if (cpr == null) {
10325                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10326                    mProviderMap.putProviderByClass(comp, cpr);
10327                }
10328                if (DEBUG_MU) Slog.v(TAG_MU,
10329                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10330                app.pubProviders.put(cpi.name, cpr);
10331                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10332                    // Don't add this if it is a platform component that is marked
10333                    // to run in multiple processes, because this is actually
10334                    // part of the framework so doesn't make sense to track as a
10335                    // separate apk in the process.
10336                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10337                            mProcessStats);
10338                }
10339                notifyPackageUse(cpi.applicationInfo.packageName,
10340                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10341            }
10342        }
10343        return providers;
10344    }
10345
10346    /**
10347     * Check if {@link ProcessRecord} has a possible chance at accessing the
10348     * given {@link ProviderInfo}. Final permission checking is always done
10349     * in {@link ContentProvider}.
10350     */
10351    private final String checkContentProviderPermissionLocked(
10352            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10353        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10354        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10355        boolean checkedGrants = false;
10356        if (checkUser) {
10357            // Looking for cross-user grants before enforcing the typical cross-users permissions
10358            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10359            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10360                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10361                    return null;
10362                }
10363                checkedGrants = true;
10364            }
10365            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10366                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10367            if (userId != tmpTargetUserId) {
10368                // When we actually went to determine the final targer user ID, this ended
10369                // up different than our initial check for the authority.  This is because
10370                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10371                // SELF.  So we need to re-check the grants again.
10372                checkedGrants = false;
10373            }
10374        }
10375        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10376                cpi.applicationInfo.uid, cpi.exported)
10377                == PackageManager.PERMISSION_GRANTED) {
10378            return null;
10379        }
10380        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10381                cpi.applicationInfo.uid, cpi.exported)
10382                == PackageManager.PERMISSION_GRANTED) {
10383            return null;
10384        }
10385
10386        PathPermission[] pps = cpi.pathPermissions;
10387        if (pps != null) {
10388            int i = pps.length;
10389            while (i > 0) {
10390                i--;
10391                PathPermission pp = pps[i];
10392                String pprperm = pp.getReadPermission();
10393                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10394                        cpi.applicationInfo.uid, cpi.exported)
10395                        == PackageManager.PERMISSION_GRANTED) {
10396                    return null;
10397                }
10398                String ppwperm = pp.getWritePermission();
10399                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10400                        cpi.applicationInfo.uid, cpi.exported)
10401                        == PackageManager.PERMISSION_GRANTED) {
10402                    return null;
10403                }
10404            }
10405        }
10406        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10407            return null;
10408        }
10409
10410        String msg;
10411        if (!cpi.exported) {
10412            msg = "Permission Denial: opening provider " + cpi.name
10413                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10414                    + ", uid=" + callingUid + ") that is not exported from uid "
10415                    + cpi.applicationInfo.uid;
10416        } else {
10417            msg = "Permission Denial: opening provider " + cpi.name
10418                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10419                    + ", uid=" + callingUid + ") requires "
10420                    + cpi.readPermission + " or " + cpi.writePermission;
10421        }
10422        Slog.w(TAG, msg);
10423        return msg;
10424    }
10425
10426    /**
10427     * Returns if the ContentProvider has granted a uri to callingUid
10428     */
10429    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10430        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10431        if (perms != null) {
10432            for (int i=perms.size()-1; i>=0; i--) {
10433                GrantUri grantUri = perms.keyAt(i);
10434                if (grantUri.sourceUserId == userId || !checkUser) {
10435                    if (matchesProvider(grantUri.uri, cpi)) {
10436                        return true;
10437                    }
10438                }
10439            }
10440        }
10441        return false;
10442    }
10443
10444    /**
10445     * Returns true if the uri authority is one of the authorities specified in the provider.
10446     */
10447    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10448        String uriAuth = uri.getAuthority();
10449        String cpiAuth = cpi.authority;
10450        if (cpiAuth.indexOf(';') == -1) {
10451            return cpiAuth.equals(uriAuth);
10452        }
10453        String[] cpiAuths = cpiAuth.split(";");
10454        int length = cpiAuths.length;
10455        for (int i = 0; i < length; i++) {
10456            if (cpiAuths[i].equals(uriAuth)) return true;
10457        }
10458        return false;
10459    }
10460
10461    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10462            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10463        if (r != null) {
10464            for (int i=0; i<r.conProviders.size(); i++) {
10465                ContentProviderConnection conn = r.conProviders.get(i);
10466                if (conn.provider == cpr) {
10467                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10468                            "Adding provider requested by "
10469                            + r.processName + " from process "
10470                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10471                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10472                    if (stable) {
10473                        conn.stableCount++;
10474                        conn.numStableIncs++;
10475                    } else {
10476                        conn.unstableCount++;
10477                        conn.numUnstableIncs++;
10478                    }
10479                    return conn;
10480                }
10481            }
10482            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10483            if (stable) {
10484                conn.stableCount = 1;
10485                conn.numStableIncs = 1;
10486            } else {
10487                conn.unstableCount = 1;
10488                conn.numUnstableIncs = 1;
10489            }
10490            cpr.connections.add(conn);
10491            r.conProviders.add(conn);
10492            startAssociationLocked(r.uid, r.processName, r.curProcState,
10493                    cpr.uid, cpr.name, cpr.info.processName);
10494            return conn;
10495        }
10496        cpr.addExternalProcessHandleLocked(externalProcessToken);
10497        return null;
10498    }
10499
10500    boolean decProviderCountLocked(ContentProviderConnection conn,
10501            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10502        if (conn != null) {
10503            cpr = conn.provider;
10504            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10505                    "Removing provider requested by "
10506                    + conn.client.processName + " from process "
10507                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10508                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10509            if (stable) {
10510                conn.stableCount--;
10511            } else {
10512                conn.unstableCount--;
10513            }
10514            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10515                cpr.connections.remove(conn);
10516                conn.client.conProviders.remove(conn);
10517                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10518                    // The client is more important than last activity -- note the time this
10519                    // is happening, so we keep the old provider process around a bit as last
10520                    // activity to avoid thrashing it.
10521                    if (cpr.proc != null) {
10522                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10523                    }
10524                }
10525                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10526                return true;
10527            }
10528            return false;
10529        }
10530        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10531        return false;
10532    }
10533
10534    private void checkTime(long startTime, String where) {
10535        long now = SystemClock.uptimeMillis();
10536        if ((now-startTime) > 50) {
10537            // If we are taking more than 50ms, log about it.
10538            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10539        }
10540    }
10541
10542    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10543            PROC_SPACE_TERM,
10544            PROC_SPACE_TERM|PROC_PARENS,
10545            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10546    };
10547
10548    private final long[] mProcessStateStatsLongs = new long[1];
10549
10550    boolean isProcessAliveLocked(ProcessRecord proc) {
10551        if (proc.procStatFile == null) {
10552            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10553        }
10554        mProcessStateStatsLongs[0] = 0;
10555        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10556                mProcessStateStatsLongs, null)) {
10557            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10558            return false;
10559        }
10560        final long state = mProcessStateStatsLongs[0];
10561        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10562                + (char)state);
10563        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10564    }
10565
10566    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10567            String name, IBinder token, boolean stable, int userId) {
10568        ContentProviderRecord cpr;
10569        ContentProviderConnection conn = null;
10570        ProviderInfo cpi = null;
10571
10572        synchronized(this) {
10573            long startTime = SystemClock.uptimeMillis();
10574
10575            ProcessRecord r = null;
10576            if (caller != null) {
10577                r = getRecordForAppLocked(caller);
10578                if (r == null) {
10579                    throw new SecurityException(
10580                            "Unable to find app for caller " + caller
10581                          + " (pid=" + Binder.getCallingPid()
10582                          + ") when getting content provider " + name);
10583                }
10584            }
10585
10586            boolean checkCrossUser = true;
10587
10588            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10589
10590            // First check if this content provider has been published...
10591            cpr = mProviderMap.getProviderByName(name, userId);
10592            // If that didn't work, check if it exists for user 0 and then
10593            // verify that it's a singleton provider before using it.
10594            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10595                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10596                if (cpr != null) {
10597                    cpi = cpr.info;
10598                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10599                            cpi.name, cpi.flags)
10600                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10601                        userId = UserHandle.USER_SYSTEM;
10602                        checkCrossUser = false;
10603                    } else {
10604                        cpr = null;
10605                        cpi = null;
10606                    }
10607                }
10608            }
10609
10610            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10611            if (providerRunning) {
10612                cpi = cpr.info;
10613                String msg;
10614                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10615                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10616                        != null) {
10617                    throw new SecurityException(msg);
10618                }
10619                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10620
10621                if (r != null && cpr.canRunHere(r)) {
10622                    // This provider has been published or is in the process
10623                    // of being published...  but it is also allowed to run
10624                    // in the caller's process, so don't make a connection
10625                    // and just let the caller instantiate its own instance.
10626                    ContentProviderHolder holder = cpr.newHolder(null);
10627                    // don't give caller the provider object, it needs
10628                    // to make its own.
10629                    holder.provider = null;
10630                    return holder;
10631                }
10632
10633                final long origId = Binder.clearCallingIdentity();
10634
10635                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10636
10637                // In this case the provider instance already exists, so we can
10638                // return it right away.
10639                conn = incProviderCountLocked(r, cpr, token, stable);
10640                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10641                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10642                        // If this is a perceptible app accessing the provider,
10643                        // make sure to count it as being accessed and thus
10644                        // back up on the LRU list.  This is good because
10645                        // content providers are often expensive to start.
10646                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10647                        updateLruProcessLocked(cpr.proc, false, null);
10648                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10649                    }
10650                }
10651
10652                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10653                final int verifiedAdj = cpr.proc.verifiedAdj;
10654                boolean success = updateOomAdjLocked(cpr.proc);
10655                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10656                // if the process has been successfully adjusted.  So to reduce races with
10657                // it, we will check whether the process still exists.  Note that this doesn't
10658                // completely get rid of races with LMK killing the process, but should make
10659                // them much smaller.
10660                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10661                    success = false;
10662                }
10663                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10664                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10665                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10666                // NOTE: there is still a race here where a signal could be
10667                // pending on the process even though we managed to update its
10668                // adj level.  Not sure what to do about this, but at least
10669                // the race is now smaller.
10670                if (!success) {
10671                    // Uh oh...  it looks like the provider's process
10672                    // has been killed on us.  We need to wait for a new
10673                    // process to be started, and make sure its death
10674                    // doesn't kill our process.
10675                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10676                            + " is crashing; detaching " + r);
10677                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10678                    checkTime(startTime, "getContentProviderImpl: before appDied");
10679                    appDiedLocked(cpr.proc);
10680                    checkTime(startTime, "getContentProviderImpl: after appDied");
10681                    if (!lastRef) {
10682                        // This wasn't the last ref our process had on
10683                        // the provider...  we have now been killed, bail.
10684                        return null;
10685                    }
10686                    providerRunning = false;
10687                    conn = null;
10688                } else {
10689                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10690                }
10691
10692                Binder.restoreCallingIdentity(origId);
10693            }
10694
10695            if (!providerRunning) {
10696                try {
10697                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10698                    cpi = AppGlobals.getPackageManager().
10699                        resolveContentProvider(name,
10700                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10701                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10702                } catch (RemoteException ex) {
10703                }
10704                if (cpi == null) {
10705                    return null;
10706                }
10707                // If the provider is a singleton AND
10708                // (it's a call within the same user || the provider is a
10709                // privileged app)
10710                // Then allow connecting to the singleton provider
10711                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10712                        cpi.name, cpi.flags)
10713                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10714                if (singleton) {
10715                    userId = UserHandle.USER_SYSTEM;
10716                }
10717                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10718                checkTime(startTime, "getContentProviderImpl: got app info for user");
10719
10720                String msg;
10721                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10722                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10723                        != null) {
10724                    throw new SecurityException(msg);
10725                }
10726                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10727
10728                if (!mProcessesReady
10729                        && !cpi.processName.equals("system")) {
10730                    // If this content provider does not run in the system
10731                    // process, and the system is not yet ready to run other
10732                    // processes, then fail fast instead of hanging.
10733                    throw new IllegalArgumentException(
10734                            "Attempt to launch content provider before system ready");
10735                }
10736
10737                // Make sure that the user who owns this provider is running.  If not,
10738                // we don't want to allow it to run.
10739                if (!mUserController.isUserRunningLocked(userId, 0)) {
10740                    Slog.w(TAG, "Unable to launch app "
10741                            + cpi.applicationInfo.packageName + "/"
10742                            + cpi.applicationInfo.uid + " for provider "
10743                            + name + ": user " + userId + " is stopped");
10744                    return null;
10745                }
10746
10747                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10748                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10749                cpr = mProviderMap.getProviderByClass(comp, userId);
10750                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10751                final boolean firstClass = cpr == null;
10752                if (firstClass) {
10753                    final long ident = Binder.clearCallingIdentity();
10754
10755                    // If permissions need a review before any of the app components can run,
10756                    // we return no provider and launch a review activity if the calling app
10757                    // is in the foreground.
10758                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10759                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10760                            return null;
10761                        }
10762                    }
10763
10764                    try {
10765                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10766                        ApplicationInfo ai =
10767                            AppGlobals.getPackageManager().
10768                                getApplicationInfo(
10769                                        cpi.applicationInfo.packageName,
10770                                        STOCK_PM_FLAGS, userId);
10771                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10772                        if (ai == null) {
10773                            Slog.w(TAG, "No package info for content provider "
10774                                    + cpi.name);
10775                            return null;
10776                        }
10777                        ai = getAppInfoForUser(ai, userId);
10778                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10779                    } catch (RemoteException ex) {
10780                        // pm is in same process, this will never happen.
10781                    } finally {
10782                        Binder.restoreCallingIdentity(ident);
10783                    }
10784                }
10785
10786                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10787
10788                if (r != null && cpr.canRunHere(r)) {
10789                    // If this is a multiprocess provider, then just return its
10790                    // info and allow the caller to instantiate it.  Only do
10791                    // this if the provider is the same user as the caller's
10792                    // process, or can run as root (so can be in any process).
10793                    return cpr.newHolder(null);
10794                }
10795
10796                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10797                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10798                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10799
10800                // This is single process, and our app is now connecting to it.
10801                // See if we are already in the process of launching this
10802                // provider.
10803                final int N = mLaunchingProviders.size();
10804                int i;
10805                for (i = 0; i < N; i++) {
10806                    if (mLaunchingProviders.get(i) == cpr) {
10807                        break;
10808                    }
10809                }
10810
10811                // If the provider is not already being launched, then get it
10812                // started.
10813                if (i >= N) {
10814                    final long origId = Binder.clearCallingIdentity();
10815
10816                    try {
10817                        // Content provider is now in use, its package can't be stopped.
10818                        try {
10819                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10820                            AppGlobals.getPackageManager().setPackageStoppedState(
10821                                    cpr.appInfo.packageName, false, userId);
10822                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10823                        } catch (RemoteException e) {
10824                        } catch (IllegalArgumentException e) {
10825                            Slog.w(TAG, "Failed trying to unstop package "
10826                                    + cpr.appInfo.packageName + ": " + e);
10827                        }
10828
10829                        // Use existing process if already started
10830                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10831                        ProcessRecord proc = getProcessRecordLocked(
10832                                cpi.processName, cpr.appInfo.uid, false);
10833                        if (proc != null && proc.thread != null && !proc.killed) {
10834                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10835                                    "Installing in existing process " + proc);
10836                            if (!proc.pubProviders.containsKey(cpi.name)) {
10837                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10838                                proc.pubProviders.put(cpi.name, cpr);
10839                                try {
10840                                    proc.thread.scheduleInstallProvider(cpi);
10841                                } catch (RemoteException e) {
10842                                }
10843                            }
10844                        } else {
10845                            checkTime(startTime, "getContentProviderImpl: before start process");
10846                            proc = startProcessLocked(cpi.processName,
10847                                    cpr.appInfo, false, 0, "content provider",
10848                                    new ComponentName(cpi.applicationInfo.packageName,
10849                                            cpi.name), false, false, false);
10850                            checkTime(startTime, "getContentProviderImpl: after start process");
10851                            if (proc == null) {
10852                                Slog.w(TAG, "Unable to launch app "
10853                                        + cpi.applicationInfo.packageName + "/"
10854                                        + cpi.applicationInfo.uid + " for provider "
10855                                        + name + ": process is bad");
10856                                return null;
10857                            }
10858                        }
10859                        cpr.launchingApp = proc;
10860                        mLaunchingProviders.add(cpr);
10861                    } finally {
10862                        Binder.restoreCallingIdentity(origId);
10863                    }
10864                }
10865
10866                checkTime(startTime, "getContentProviderImpl: updating data structures");
10867
10868                // Make sure the provider is published (the same provider class
10869                // may be published under multiple names).
10870                if (firstClass) {
10871                    mProviderMap.putProviderByClass(comp, cpr);
10872                }
10873
10874                mProviderMap.putProviderByName(name, cpr);
10875                conn = incProviderCountLocked(r, cpr, token, stable);
10876                if (conn != null) {
10877                    conn.waiting = true;
10878                }
10879            }
10880            checkTime(startTime, "getContentProviderImpl: done!");
10881        }
10882
10883        // Wait for the provider to be published...
10884        synchronized (cpr) {
10885            while (cpr.provider == null) {
10886                if (cpr.launchingApp == null) {
10887                    Slog.w(TAG, "Unable to launch app "
10888                            + cpi.applicationInfo.packageName + "/"
10889                            + cpi.applicationInfo.uid + " for provider "
10890                            + name + ": launching app became null");
10891                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10892                            UserHandle.getUserId(cpi.applicationInfo.uid),
10893                            cpi.applicationInfo.packageName,
10894                            cpi.applicationInfo.uid, name);
10895                    return null;
10896                }
10897                try {
10898                    if (DEBUG_MU) Slog.v(TAG_MU,
10899                            "Waiting to start provider " + cpr
10900                            + " launchingApp=" + cpr.launchingApp);
10901                    if (conn != null) {
10902                        conn.waiting = true;
10903                    }
10904                    cpr.wait();
10905                } catch (InterruptedException ex) {
10906                } finally {
10907                    if (conn != null) {
10908                        conn.waiting = false;
10909                    }
10910                }
10911            }
10912        }
10913        return cpr != null ? cpr.newHolder(conn) : null;
10914    }
10915
10916    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10917            ProcessRecord r, final int userId) {
10918        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10919                cpi.packageName, userId)) {
10920
10921            final boolean callerForeground = r == null || r.setSchedGroup
10922                    != ProcessList.SCHED_GROUP_BACKGROUND;
10923
10924            // Show a permission review UI only for starting from a foreground app
10925            if (!callerForeground) {
10926                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10927                        + cpi.packageName + " requires a permissions review");
10928                return false;
10929            }
10930
10931            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10932            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10933                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10934            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10935
10936            if (DEBUG_PERMISSIONS_REVIEW) {
10937                Slog.i(TAG, "u" + userId + " Launching permission review "
10938                        + "for package " + cpi.packageName);
10939            }
10940
10941            final UserHandle userHandle = new UserHandle(userId);
10942            mHandler.post(new Runnable() {
10943                @Override
10944                public void run() {
10945                    mContext.startActivityAsUser(intent, userHandle);
10946                }
10947            });
10948
10949            return false;
10950        }
10951
10952        return true;
10953    }
10954
10955    PackageManagerInternal getPackageManagerInternalLocked() {
10956        if (mPackageManagerInt == null) {
10957            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10958        }
10959        return mPackageManagerInt;
10960    }
10961
10962    @Override
10963    public final ContentProviderHolder getContentProvider(
10964            IApplicationThread caller, String name, int userId, boolean stable) {
10965        enforceNotIsolatedCaller("getContentProvider");
10966        if (caller == null) {
10967            String msg = "null IApplicationThread when getting content provider "
10968                    + name;
10969            Slog.w(TAG, msg);
10970            throw new SecurityException(msg);
10971        }
10972        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10973        // with cross-user grant.
10974        return getContentProviderImpl(caller, name, null, stable, userId);
10975    }
10976
10977    public ContentProviderHolder getContentProviderExternal(
10978            String name, int userId, IBinder token) {
10979        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10980            "Do not have permission in call getContentProviderExternal()");
10981        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10982                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10983        return getContentProviderExternalUnchecked(name, token, userId);
10984    }
10985
10986    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10987            IBinder token, int userId) {
10988        return getContentProviderImpl(null, name, token, true, userId);
10989    }
10990
10991    /**
10992     * Drop a content provider from a ProcessRecord's bookkeeping
10993     */
10994    public void removeContentProvider(IBinder connection, boolean stable) {
10995        enforceNotIsolatedCaller("removeContentProvider");
10996        long ident = Binder.clearCallingIdentity();
10997        try {
10998            synchronized (this) {
10999                ContentProviderConnection conn;
11000                try {
11001                    conn = (ContentProviderConnection)connection;
11002                } catch (ClassCastException e) {
11003                    String msg ="removeContentProvider: " + connection
11004                            + " not a ContentProviderConnection";
11005                    Slog.w(TAG, msg);
11006                    throw new IllegalArgumentException(msg);
11007                }
11008                if (conn == null) {
11009                    throw new NullPointerException("connection is null");
11010                }
11011                if (decProviderCountLocked(conn, null, null, stable)) {
11012                    updateOomAdjLocked();
11013                }
11014            }
11015        } finally {
11016            Binder.restoreCallingIdentity(ident);
11017        }
11018    }
11019
11020    public void removeContentProviderExternal(String name, IBinder token) {
11021        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11022            "Do not have permission in call removeContentProviderExternal()");
11023        int userId = UserHandle.getCallingUserId();
11024        long ident = Binder.clearCallingIdentity();
11025        try {
11026            removeContentProviderExternalUnchecked(name, token, userId);
11027        } finally {
11028            Binder.restoreCallingIdentity(ident);
11029        }
11030    }
11031
11032    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11033        synchronized (this) {
11034            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11035            if(cpr == null) {
11036                //remove from mProvidersByClass
11037                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11038                return;
11039            }
11040
11041            //update content provider record entry info
11042            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11043            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11044            if (localCpr.hasExternalProcessHandles()) {
11045                if (localCpr.removeExternalProcessHandleLocked(token)) {
11046                    updateOomAdjLocked();
11047                } else {
11048                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11049                            + " with no external reference for token: "
11050                            + token + ".");
11051                }
11052            } else {
11053                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11054                        + " with no external references.");
11055            }
11056        }
11057    }
11058
11059    public final void publishContentProviders(IApplicationThread caller,
11060            List<ContentProviderHolder> providers) {
11061        if (providers == null) {
11062            return;
11063        }
11064
11065        enforceNotIsolatedCaller("publishContentProviders");
11066        synchronized (this) {
11067            final ProcessRecord r = getRecordForAppLocked(caller);
11068            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11069            if (r == null) {
11070                throw new SecurityException(
11071                        "Unable to find app for caller " + caller
11072                      + " (pid=" + Binder.getCallingPid()
11073                      + ") when publishing content providers");
11074            }
11075
11076            final long origId = Binder.clearCallingIdentity();
11077
11078            final int N = providers.size();
11079            for (int i = 0; i < N; i++) {
11080                ContentProviderHolder src = providers.get(i);
11081                if (src == null || src.info == null || src.provider == null) {
11082                    continue;
11083                }
11084                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11085                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11086                if (dst != null) {
11087                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11088                    mProviderMap.putProviderByClass(comp, dst);
11089                    String names[] = dst.info.authority.split(";");
11090                    for (int j = 0; j < names.length; j++) {
11091                        mProviderMap.putProviderByName(names[j], dst);
11092                    }
11093
11094                    int launchingCount = mLaunchingProviders.size();
11095                    int j;
11096                    boolean wasInLaunchingProviders = false;
11097                    for (j = 0; j < launchingCount; j++) {
11098                        if (mLaunchingProviders.get(j) == dst) {
11099                            mLaunchingProviders.remove(j);
11100                            wasInLaunchingProviders = true;
11101                            j--;
11102                            launchingCount--;
11103                        }
11104                    }
11105                    if (wasInLaunchingProviders) {
11106                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11107                    }
11108                    synchronized (dst) {
11109                        dst.provider = src.provider;
11110                        dst.proc = r;
11111                        dst.notifyAll();
11112                    }
11113                    updateOomAdjLocked(r);
11114                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11115                            src.info.authority);
11116                }
11117            }
11118
11119            Binder.restoreCallingIdentity(origId);
11120        }
11121    }
11122
11123    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11124        ContentProviderConnection conn;
11125        try {
11126            conn = (ContentProviderConnection)connection;
11127        } catch (ClassCastException e) {
11128            String msg ="refContentProvider: " + connection
11129                    + " not a ContentProviderConnection";
11130            Slog.w(TAG, msg);
11131            throw new IllegalArgumentException(msg);
11132        }
11133        if (conn == null) {
11134            throw new NullPointerException("connection is null");
11135        }
11136
11137        synchronized (this) {
11138            if (stable > 0) {
11139                conn.numStableIncs += stable;
11140            }
11141            stable = conn.stableCount + stable;
11142            if (stable < 0) {
11143                throw new IllegalStateException("stableCount < 0: " + stable);
11144            }
11145
11146            if (unstable > 0) {
11147                conn.numUnstableIncs += unstable;
11148            }
11149            unstable = conn.unstableCount + unstable;
11150            if (unstable < 0) {
11151                throw new IllegalStateException("unstableCount < 0: " + unstable);
11152            }
11153
11154            if ((stable+unstable) <= 0) {
11155                throw new IllegalStateException("ref counts can't go to zero here: stable="
11156                        + stable + " unstable=" + unstable);
11157            }
11158            conn.stableCount = stable;
11159            conn.unstableCount = unstable;
11160            return !conn.dead;
11161        }
11162    }
11163
11164    public void unstableProviderDied(IBinder connection) {
11165        ContentProviderConnection conn;
11166        try {
11167            conn = (ContentProviderConnection)connection;
11168        } catch (ClassCastException e) {
11169            String msg ="refContentProvider: " + connection
11170                    + " not a ContentProviderConnection";
11171            Slog.w(TAG, msg);
11172            throw new IllegalArgumentException(msg);
11173        }
11174        if (conn == null) {
11175            throw new NullPointerException("connection is null");
11176        }
11177
11178        // Safely retrieve the content provider associated with the connection.
11179        IContentProvider provider;
11180        synchronized (this) {
11181            provider = conn.provider.provider;
11182        }
11183
11184        if (provider == null) {
11185            // Um, yeah, we're way ahead of you.
11186            return;
11187        }
11188
11189        // Make sure the caller is being honest with us.
11190        if (provider.asBinder().pingBinder()) {
11191            // Er, no, still looks good to us.
11192            synchronized (this) {
11193                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11194                        + " says " + conn + " died, but we don't agree");
11195                return;
11196            }
11197        }
11198
11199        // Well look at that!  It's dead!
11200        synchronized (this) {
11201            if (conn.provider.provider != provider) {
11202                // But something changed...  good enough.
11203                return;
11204            }
11205
11206            ProcessRecord proc = conn.provider.proc;
11207            if (proc == null || proc.thread == null) {
11208                // Seems like the process is already cleaned up.
11209                return;
11210            }
11211
11212            // As far as we're concerned, this is just like receiving a
11213            // death notification...  just a bit prematurely.
11214            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11215                    + ") early provider death");
11216            final long ident = Binder.clearCallingIdentity();
11217            try {
11218                appDiedLocked(proc);
11219            } finally {
11220                Binder.restoreCallingIdentity(ident);
11221            }
11222        }
11223    }
11224
11225    @Override
11226    public void appNotRespondingViaProvider(IBinder connection) {
11227        enforceCallingPermission(
11228                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11229
11230        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11231        if (conn == null) {
11232            Slog.w(TAG, "ContentProviderConnection is null");
11233            return;
11234        }
11235
11236        final ProcessRecord host = conn.provider.proc;
11237        if (host == null) {
11238            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11239            return;
11240        }
11241
11242        mHandler.post(new Runnable() {
11243            @Override
11244            public void run() {
11245                mAppErrors.appNotResponding(host, null, null, false,
11246                        "ContentProvider not responding");
11247            }
11248        });
11249    }
11250
11251    public final void installSystemProviders() {
11252        List<ProviderInfo> providers;
11253        synchronized (this) {
11254            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11255            providers = generateApplicationProvidersLocked(app);
11256            if (providers != null) {
11257                for (int i=providers.size()-1; i>=0; i--) {
11258                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11259                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11260                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11261                                + ": not system .apk");
11262                        providers.remove(i);
11263                    }
11264                }
11265            }
11266        }
11267        if (providers != null) {
11268            mSystemThread.installSystemProviders(providers);
11269        }
11270
11271        mCoreSettingsObserver = new CoreSettingsObserver(this);
11272        mFontScaleSettingObserver = new FontScaleSettingObserver();
11273
11274        //mUsageStatsService.monitorPackages();
11275    }
11276
11277    private void startPersistentApps(int matchFlags) {
11278        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11279
11280        synchronized (this) {
11281            try {
11282                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11283                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11284                for (ApplicationInfo app : apps) {
11285                    if (!"android".equals(app.packageName)) {
11286                        addAppLocked(app, false, null /* ABI override */);
11287                    }
11288                }
11289            } catch (RemoteException ex) {
11290            }
11291        }
11292    }
11293
11294    /**
11295     * When a user is unlocked, we need to install encryption-unaware providers
11296     * belonging to any running apps.
11297     */
11298    private void installEncryptionUnawareProviders(int userId) {
11299        // We're only interested in providers that are encryption unaware, and
11300        // we don't care about uninstalled apps, since there's no way they're
11301        // running at this point.
11302        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11303
11304        synchronized (this) {
11305            final int NP = mProcessNames.getMap().size();
11306            for (int ip = 0; ip < NP; ip++) {
11307                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11308                final int NA = apps.size();
11309                for (int ia = 0; ia < NA; ia++) {
11310                    final ProcessRecord app = apps.valueAt(ia);
11311                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11312
11313                    final int NG = app.pkgList.size();
11314                    for (int ig = 0; ig < NG; ig++) {
11315                        try {
11316                            final String pkgName = app.pkgList.keyAt(ig);
11317                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11318                                    .getPackageInfo(pkgName, matchFlags, userId);
11319                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11320                                for (ProviderInfo pi : pkgInfo.providers) {
11321                                    // TODO: keep in sync with generateApplicationProvidersLocked
11322                                    final boolean processMatch = Objects.equals(pi.processName,
11323                                            app.processName) || pi.multiprocess;
11324                                    final boolean userMatch = isSingleton(pi.processName,
11325                                            pi.applicationInfo, pi.name, pi.flags)
11326                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11327                                    if (processMatch && userMatch) {
11328                                        Log.v(TAG, "Installing " + pi);
11329                                        app.thread.scheduleInstallProvider(pi);
11330                                    } else {
11331                                        Log.v(TAG, "Skipping " + pi);
11332                                    }
11333                                }
11334                            }
11335                        } catch (RemoteException ignored) {
11336                        }
11337                    }
11338                }
11339            }
11340        }
11341    }
11342
11343    /**
11344     * Allows apps to retrieve the MIME type of a URI.
11345     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11346     * users, then it does not need permission to access the ContentProvider.
11347     * Either, it needs cross-user uri grants.
11348     *
11349     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11350     *
11351     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11352     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11353     */
11354    public String getProviderMimeType(Uri uri, int userId) {
11355        enforceNotIsolatedCaller("getProviderMimeType");
11356        final String name = uri.getAuthority();
11357        int callingUid = Binder.getCallingUid();
11358        int callingPid = Binder.getCallingPid();
11359        long ident = 0;
11360        boolean clearedIdentity = false;
11361        synchronized (this) {
11362            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11363        }
11364        if (canClearIdentity(callingPid, callingUid, userId)) {
11365            clearedIdentity = true;
11366            ident = Binder.clearCallingIdentity();
11367        }
11368        ContentProviderHolder holder = null;
11369        try {
11370            holder = getContentProviderExternalUnchecked(name, null, userId);
11371            if (holder != null) {
11372                return holder.provider.getType(uri);
11373            }
11374        } catch (RemoteException e) {
11375            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11376            return null;
11377        } catch (Exception e) {
11378            Log.w(TAG, "Exception while determining type of " + uri, e);
11379            return null;
11380        } finally {
11381            // We need to clear the identity to call removeContentProviderExternalUnchecked
11382            if (!clearedIdentity) {
11383                ident = Binder.clearCallingIdentity();
11384            }
11385            try {
11386                if (holder != null) {
11387                    removeContentProviderExternalUnchecked(name, null, userId);
11388                }
11389            } finally {
11390                Binder.restoreCallingIdentity(ident);
11391            }
11392        }
11393
11394        return null;
11395    }
11396
11397    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11398        if (UserHandle.getUserId(callingUid) == userId) {
11399            return true;
11400        }
11401        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11402                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11403                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11404                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11405                return true;
11406        }
11407        return false;
11408    }
11409
11410    // =========================================================
11411    // GLOBAL MANAGEMENT
11412    // =========================================================
11413
11414    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11415            boolean isolated, int isolatedUid) {
11416        String proc = customProcess != null ? customProcess : info.processName;
11417        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11418        final int userId = UserHandle.getUserId(info.uid);
11419        int uid = info.uid;
11420        if (isolated) {
11421            if (isolatedUid == 0) {
11422                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11423                while (true) {
11424                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11425                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11426                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11427                    }
11428                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11429                    mNextIsolatedProcessUid++;
11430                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11431                        // No process for this uid, use it.
11432                        break;
11433                    }
11434                    stepsLeft--;
11435                    if (stepsLeft <= 0) {
11436                        return null;
11437                    }
11438                }
11439            } else {
11440                // Special case for startIsolatedProcess (internal only), where
11441                // the uid of the isolated process is specified by the caller.
11442                uid = isolatedUid;
11443            }
11444        }
11445        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11446        if (!mBooted && !mBooting
11447                && userId == UserHandle.USER_SYSTEM
11448                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11449            r.persistent = true;
11450        }
11451        addProcessNameLocked(r);
11452        return r;
11453    }
11454
11455    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11456            String abiOverride) {
11457        ProcessRecord app;
11458        if (!isolated) {
11459            app = getProcessRecordLocked(info.processName, info.uid, true);
11460        } else {
11461            app = null;
11462        }
11463
11464        if (app == null) {
11465            app = newProcessRecordLocked(info, null, isolated, 0);
11466            updateLruProcessLocked(app, false, null);
11467            updateOomAdjLocked();
11468        }
11469
11470        // This package really, really can not be stopped.
11471        try {
11472            AppGlobals.getPackageManager().setPackageStoppedState(
11473                    info.packageName, false, UserHandle.getUserId(app.uid));
11474        } catch (RemoteException e) {
11475        } catch (IllegalArgumentException e) {
11476            Slog.w(TAG, "Failed trying to unstop package "
11477                    + info.packageName + ": " + e);
11478        }
11479
11480        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11481            app.persistent = true;
11482            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11483        }
11484        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11485            mPersistentStartingProcesses.add(app);
11486            startProcessLocked(app, "added application", app.processName, abiOverride,
11487                    null /* entryPoint */, null /* entryPointArgs */);
11488        }
11489
11490        return app;
11491    }
11492
11493    public void unhandledBack() {
11494        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11495                "unhandledBack()");
11496
11497        synchronized(this) {
11498            final long origId = Binder.clearCallingIdentity();
11499            try {
11500                getFocusedStack().unhandledBackLocked();
11501            } finally {
11502                Binder.restoreCallingIdentity(origId);
11503            }
11504        }
11505    }
11506
11507    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11508        enforceNotIsolatedCaller("openContentUri");
11509        final int userId = UserHandle.getCallingUserId();
11510        String name = uri.getAuthority();
11511        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11512        ParcelFileDescriptor pfd = null;
11513        if (cph != null) {
11514            // We record the binder invoker's uid in thread-local storage before
11515            // going to the content provider to open the file.  Later, in the code
11516            // that handles all permissions checks, we look for this uid and use
11517            // that rather than the Activity Manager's own uid.  The effect is that
11518            // we do the check against the caller's permissions even though it looks
11519            // to the content provider like the Activity Manager itself is making
11520            // the request.
11521            Binder token = new Binder();
11522            sCallerIdentity.set(new Identity(
11523                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11524            try {
11525                pfd = cph.provider.openFile(null, uri, "r", null, token);
11526            } catch (FileNotFoundException e) {
11527                // do nothing; pfd will be returned null
11528            } finally {
11529                // Ensure that whatever happens, we clean up the identity state
11530                sCallerIdentity.remove();
11531                // Ensure we're done with the provider.
11532                removeContentProviderExternalUnchecked(name, null, userId);
11533            }
11534        } else {
11535            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11536        }
11537        return pfd;
11538    }
11539
11540    // Actually is sleeping or shutting down or whatever else in the future
11541    // is an inactive state.
11542    boolean isSleepingOrShuttingDownLocked() {
11543        return isSleepingLocked() || mShuttingDown;
11544    }
11545
11546    boolean isShuttingDownLocked() {
11547        return mShuttingDown;
11548    }
11549
11550    boolean isSleepingLocked() {
11551        return mSleeping;
11552    }
11553
11554    void onWakefulnessChanged(int wakefulness) {
11555        synchronized(this) {
11556            mWakefulness = wakefulness;
11557            updateSleepIfNeededLocked();
11558        }
11559    }
11560
11561    void finishRunningVoiceLocked() {
11562        if (mRunningVoice != null) {
11563            mRunningVoice = null;
11564            mVoiceWakeLock.release();
11565            updateSleepIfNeededLocked();
11566        }
11567    }
11568
11569    void startTimeTrackingFocusedActivityLocked() {
11570        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11571            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11572        }
11573    }
11574
11575    void updateSleepIfNeededLocked() {
11576        if (mSleeping && !shouldSleepLocked()) {
11577            mSleeping = false;
11578            startTimeTrackingFocusedActivityLocked();
11579            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11580            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11581            updateOomAdjLocked();
11582        } else if (!mSleeping && shouldSleepLocked()) {
11583            mSleeping = true;
11584            if (mCurAppTimeTracker != null) {
11585                mCurAppTimeTracker.stop();
11586            }
11587            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11588            mStackSupervisor.goingToSleepLocked();
11589            updateOomAdjLocked();
11590
11591            // Initialize the wake times of all processes.
11592            checkExcessivePowerUsageLocked(false);
11593            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11594            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11595            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11596        }
11597    }
11598
11599    private boolean shouldSleepLocked() {
11600        // Resume applications while running a voice interactor.
11601        if (mRunningVoice != null) {
11602            return false;
11603        }
11604
11605        // TODO: Transform the lock screen state into a sleep token instead.
11606        switch (mWakefulness) {
11607            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11608            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11609            case PowerManagerInternal.WAKEFULNESS_DOZING:
11610                // Pause applications whenever the lock screen is shown or any sleep
11611                // tokens have been acquired.
11612                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11613            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11614            default:
11615                // If we're asleep then pause applications unconditionally.
11616                return true;
11617        }
11618    }
11619
11620    /** Pokes the task persister. */
11621    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11622        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11623    }
11624
11625    /** Notifies all listeners when the task stack has changed. */
11626    void notifyTaskStackChangedLocked() {
11627        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11628        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11629        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11630        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11631    }
11632
11633    /** Notifies all listeners when an Activity is pinned. */
11634    void notifyActivityPinnedLocked() {
11635        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11636        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11637    }
11638
11639    /**
11640     * Notifies all listeners when an attempt was made to start an an activity that is already
11641     * running in the pinned stack and the activity was not actually started, but the task is
11642     * either brought to the front or a new Intent is delivered to it.
11643     */
11644    void notifyPinnedActivityRestartAttemptLocked() {
11645        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11646        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11647    }
11648
11649    /** Notifies all listeners when the pinned stack animation ends. */
11650    @Override
11651    public void notifyPinnedStackAnimationEnded() {
11652        synchronized (this) {
11653            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11654            mHandler.obtainMessage(
11655                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11656        }
11657    }
11658
11659    @Override
11660    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11661        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11662    }
11663
11664    @Override
11665    public boolean shutdown(int timeout) {
11666        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11667                != PackageManager.PERMISSION_GRANTED) {
11668            throw new SecurityException("Requires permission "
11669                    + android.Manifest.permission.SHUTDOWN);
11670        }
11671
11672        boolean timedout = false;
11673
11674        synchronized(this) {
11675            mShuttingDown = true;
11676            updateEventDispatchingLocked();
11677            timedout = mStackSupervisor.shutdownLocked(timeout);
11678        }
11679
11680        mAppOpsService.shutdown();
11681        if (mUsageStatsService != null) {
11682            mUsageStatsService.prepareShutdown();
11683        }
11684        mBatteryStatsService.shutdown();
11685        synchronized (this) {
11686            mProcessStats.shutdownLocked();
11687            notifyTaskPersisterLocked(null, true);
11688        }
11689
11690        return timedout;
11691    }
11692
11693    public final void activitySlept(IBinder token) {
11694        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11695
11696        final long origId = Binder.clearCallingIdentity();
11697
11698        synchronized (this) {
11699            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11700            if (r != null) {
11701                mStackSupervisor.activitySleptLocked(r);
11702            }
11703        }
11704
11705        Binder.restoreCallingIdentity(origId);
11706    }
11707
11708    private String lockScreenShownToString() {
11709        switch (mLockScreenShown) {
11710            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11711            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11712            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11713            default: return "Unknown=" + mLockScreenShown;
11714        }
11715    }
11716
11717    void logLockScreen(String msg) {
11718        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11719                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11720                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11721                + " mSleeping=" + mSleeping);
11722    }
11723
11724    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11725        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11726        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11727        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11728            boolean wasRunningVoice = mRunningVoice != null;
11729            mRunningVoice = session;
11730            if (!wasRunningVoice) {
11731                mVoiceWakeLock.acquire();
11732                updateSleepIfNeededLocked();
11733            }
11734        }
11735    }
11736
11737    private void updateEventDispatchingLocked() {
11738        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11739    }
11740
11741    public void setLockScreenShown(boolean showing, boolean occluded) {
11742        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11743                != PackageManager.PERMISSION_GRANTED) {
11744            throw new SecurityException("Requires permission "
11745                    + android.Manifest.permission.DEVICE_POWER);
11746        }
11747
11748        synchronized(this) {
11749            long ident = Binder.clearCallingIdentity();
11750            try {
11751                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11752                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11753                if (showing && occluded) {
11754                    // The lock screen is currently showing, but is occluded by a window that can
11755                    // show on top of the lock screen. In this can we want to dismiss the docked
11756                    // stack since it will be complicated/risky to try to put the activity on top
11757                    // of the lock screen in the right fullscreen configuration.
11758                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11759                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11760                }
11761
11762                updateSleepIfNeededLocked();
11763            } finally {
11764                Binder.restoreCallingIdentity(ident);
11765            }
11766        }
11767    }
11768
11769    @Override
11770    public void notifyLockedProfile(@UserIdInt int userId) {
11771        try {
11772            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11773                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11774            }
11775        } catch (RemoteException ex) {
11776            throw new SecurityException("Fail to check is caller a privileged app", ex);
11777        }
11778
11779        synchronized (this) {
11780            if (mStackSupervisor.isUserLockedProfile(userId)) {
11781                final long ident = Binder.clearCallingIdentity();
11782                try {
11783                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11784                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11785                        // If there is no device lock, we will show the profile's credential page.
11786                        mActivityStarter.showConfirmDeviceCredential(userId);
11787                    } else {
11788                        // Showing launcher to avoid user entering credential twice.
11789                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11790                    }
11791                } finally {
11792                    Binder.restoreCallingIdentity(ident);
11793                }
11794            }
11795        }
11796    }
11797
11798    @Override
11799    public void startConfirmDeviceCredentialIntent(Intent intent) {
11800        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11801        synchronized (this) {
11802            final long ident = Binder.clearCallingIdentity();
11803            try {
11804                mActivityStarter.startConfirmCredentialIntent(intent);
11805            } finally {
11806                Binder.restoreCallingIdentity(ident);
11807            }
11808        }
11809    }
11810
11811    @Override
11812    public void stopAppSwitches() {
11813        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11814                != PackageManager.PERMISSION_GRANTED) {
11815            throw new SecurityException("viewquires permission "
11816                    + android.Manifest.permission.STOP_APP_SWITCHES);
11817        }
11818
11819        synchronized(this) {
11820            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11821                    + APP_SWITCH_DELAY_TIME;
11822            mDidAppSwitch = false;
11823            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11824            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11825            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11826        }
11827    }
11828
11829    public void resumeAppSwitches() {
11830        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11831                != PackageManager.PERMISSION_GRANTED) {
11832            throw new SecurityException("Requires permission "
11833                    + android.Manifest.permission.STOP_APP_SWITCHES);
11834        }
11835
11836        synchronized(this) {
11837            // Note that we don't execute any pending app switches... we will
11838            // let those wait until either the timeout, or the next start
11839            // activity request.
11840            mAppSwitchesAllowedTime = 0;
11841        }
11842    }
11843
11844    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11845            int callingPid, int callingUid, String name) {
11846        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11847            return true;
11848        }
11849
11850        int perm = checkComponentPermission(
11851                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11852                sourceUid, -1, true);
11853        if (perm == PackageManager.PERMISSION_GRANTED) {
11854            return true;
11855        }
11856
11857        // If the actual IPC caller is different from the logical source, then
11858        // also see if they are allowed to control app switches.
11859        if (callingUid != -1 && callingUid != sourceUid) {
11860            perm = checkComponentPermission(
11861                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11862                    callingUid, -1, true);
11863            if (perm == PackageManager.PERMISSION_GRANTED) {
11864                return true;
11865            }
11866        }
11867
11868        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11869        return false;
11870    }
11871
11872    public void setDebugApp(String packageName, boolean waitForDebugger,
11873            boolean persistent) {
11874        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11875                "setDebugApp()");
11876
11877        long ident = Binder.clearCallingIdentity();
11878        try {
11879            // Note that this is not really thread safe if there are multiple
11880            // callers into it at the same time, but that's not a situation we
11881            // care about.
11882            if (persistent) {
11883                final ContentResolver resolver = mContext.getContentResolver();
11884                Settings.Global.putString(
11885                    resolver, Settings.Global.DEBUG_APP,
11886                    packageName);
11887                Settings.Global.putInt(
11888                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11889                    waitForDebugger ? 1 : 0);
11890            }
11891
11892            synchronized (this) {
11893                if (!persistent) {
11894                    mOrigDebugApp = mDebugApp;
11895                    mOrigWaitForDebugger = mWaitForDebugger;
11896                }
11897                mDebugApp = packageName;
11898                mWaitForDebugger = waitForDebugger;
11899                mDebugTransient = !persistent;
11900                if (packageName != null) {
11901                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11902                            false, UserHandle.USER_ALL, "set debug app");
11903                }
11904            }
11905        } finally {
11906            Binder.restoreCallingIdentity(ident);
11907        }
11908    }
11909
11910    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11911        synchronized (this) {
11912            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11913            if (!isDebuggable) {
11914                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11915                    throw new SecurityException("Process not debuggable: " + app.packageName);
11916                }
11917            }
11918
11919            mTrackAllocationApp = processName;
11920        }
11921    }
11922
11923    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11924        synchronized (this) {
11925            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11926            if (!isDebuggable) {
11927                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11928                    throw new SecurityException("Process not debuggable: " + app.packageName);
11929                }
11930            }
11931            mProfileApp = processName;
11932            mProfileFile = profilerInfo.profileFile;
11933            if (mProfileFd != null) {
11934                try {
11935                    mProfileFd.close();
11936                } catch (IOException e) {
11937                }
11938                mProfileFd = null;
11939            }
11940            mProfileFd = profilerInfo.profileFd;
11941            mSamplingInterval = profilerInfo.samplingInterval;
11942            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11943            mProfileType = 0;
11944        }
11945    }
11946
11947    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11948        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11949        if (!isDebuggable) {
11950            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11951                throw new SecurityException("Process not debuggable: " + app.packageName);
11952            }
11953        }
11954        mNativeDebuggingApp = processName;
11955    }
11956
11957    @Override
11958    public void setAlwaysFinish(boolean enabled) {
11959        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11960                "setAlwaysFinish()");
11961
11962        long ident = Binder.clearCallingIdentity();
11963        try {
11964            Settings.Global.putInt(
11965                    mContext.getContentResolver(),
11966                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11967
11968            synchronized (this) {
11969                mAlwaysFinishActivities = enabled;
11970            }
11971        } finally {
11972            Binder.restoreCallingIdentity(ident);
11973        }
11974    }
11975
11976    @Override
11977    public void setLenientBackgroundCheck(boolean enabled) {
11978        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11979                "setLenientBackgroundCheck()");
11980
11981        long ident = Binder.clearCallingIdentity();
11982        try {
11983            Settings.Global.putInt(
11984                    mContext.getContentResolver(),
11985                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11986
11987            synchronized (this) {
11988                mLenientBackgroundCheck = enabled;
11989            }
11990        } finally {
11991            Binder.restoreCallingIdentity(ident);
11992        }
11993    }
11994
11995    @Override
11996    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11997        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11998                "setActivityController()");
11999        synchronized (this) {
12000            mController = controller;
12001            mControllerIsAMonkey = imAMonkey;
12002            Watchdog.getInstance().setActivityController(controller);
12003        }
12004    }
12005
12006    @Override
12007    public void setUserIsMonkey(boolean userIsMonkey) {
12008        synchronized (this) {
12009            synchronized (mPidsSelfLocked) {
12010                final int callingPid = Binder.getCallingPid();
12011                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12012                if (precessRecord == null) {
12013                    throw new SecurityException("Unknown process: " + callingPid);
12014                }
12015                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12016                    throw new SecurityException("Only an instrumentation process "
12017                            + "with a UiAutomation can call setUserIsMonkey");
12018                }
12019            }
12020            mUserIsMonkey = userIsMonkey;
12021        }
12022    }
12023
12024    @Override
12025    public boolean isUserAMonkey() {
12026        synchronized (this) {
12027            // If there is a controller also implies the user is a monkey.
12028            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12029        }
12030    }
12031
12032    public void requestBugReport(int bugreportType) {
12033        String service = null;
12034        switch (bugreportType) {
12035            case ActivityManager.BUGREPORT_OPTION_FULL:
12036                service = "bugreport";
12037                break;
12038            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12039                service = "bugreportplus";
12040                break;
12041            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12042                service = "bugreportremote";
12043                break;
12044        }
12045        if (service == null) {
12046            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12047                    + bugreportType);
12048        }
12049        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12050        SystemProperties.set("ctl.start", service);
12051    }
12052
12053    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12054        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12055    }
12056
12057    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12058        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12059            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12060        }
12061        return KEY_DISPATCHING_TIMEOUT;
12062    }
12063
12064    @Override
12065    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12066        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12067                != PackageManager.PERMISSION_GRANTED) {
12068            throw new SecurityException("Requires permission "
12069                    + android.Manifest.permission.FILTER_EVENTS);
12070        }
12071        ProcessRecord proc;
12072        long timeout;
12073        synchronized (this) {
12074            synchronized (mPidsSelfLocked) {
12075                proc = mPidsSelfLocked.get(pid);
12076            }
12077            timeout = getInputDispatchingTimeoutLocked(proc);
12078        }
12079
12080        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12081            return -1;
12082        }
12083
12084        return timeout;
12085    }
12086
12087    /**
12088     * Handle input dispatching timeouts.
12089     * Returns whether input dispatching should be aborted or not.
12090     */
12091    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12092            final ActivityRecord activity, final ActivityRecord parent,
12093            final boolean aboveSystem, String reason) {
12094        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12095                != PackageManager.PERMISSION_GRANTED) {
12096            throw new SecurityException("Requires permission "
12097                    + android.Manifest.permission.FILTER_EVENTS);
12098        }
12099
12100        final String annotation;
12101        if (reason == null) {
12102            annotation = "Input dispatching timed out";
12103        } else {
12104            annotation = "Input dispatching timed out (" + reason + ")";
12105        }
12106
12107        if (proc != null) {
12108            synchronized (this) {
12109                if (proc.debugging) {
12110                    return false;
12111                }
12112
12113                if (mDidDexOpt) {
12114                    // Give more time since we were dexopting.
12115                    mDidDexOpt = false;
12116                    return false;
12117                }
12118
12119                if (proc.instrumentationClass != null) {
12120                    Bundle info = new Bundle();
12121                    info.putString("shortMsg", "keyDispatchingTimedOut");
12122                    info.putString("longMsg", annotation);
12123                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12124                    return true;
12125                }
12126            }
12127            mHandler.post(new Runnable() {
12128                @Override
12129                public void run() {
12130                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12131                }
12132            });
12133        }
12134
12135        return true;
12136    }
12137
12138    @Override
12139    public Bundle getAssistContextExtras(int requestType) {
12140        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12141                null, null, true /* focused */, true /* newSessionId */,
12142                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12143        if (pae == null) {
12144            return null;
12145        }
12146        synchronized (pae) {
12147            while (!pae.haveResult) {
12148                try {
12149                    pae.wait();
12150                } catch (InterruptedException e) {
12151                }
12152            }
12153        }
12154        synchronized (this) {
12155            buildAssistBundleLocked(pae, pae.result);
12156            mPendingAssistExtras.remove(pae);
12157            mUiHandler.removeCallbacks(pae);
12158        }
12159        return pae.extras;
12160    }
12161
12162    @Override
12163    public boolean isAssistDataAllowedOnCurrentActivity() {
12164        int userId;
12165        synchronized (this) {
12166            userId = mUserController.getCurrentUserIdLocked();
12167            ActivityRecord activity = getFocusedStack().topActivity();
12168            if (activity == null) {
12169                return false;
12170            }
12171            userId = activity.userId;
12172        }
12173        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12174                Context.DEVICE_POLICY_SERVICE);
12175        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12176    }
12177
12178    @Override
12179    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12180        long ident = Binder.clearCallingIdentity();
12181        try {
12182            synchronized (this) {
12183                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12184                ActivityRecord top = getFocusedStack().topActivity();
12185                if (top != caller) {
12186                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12187                            + " is not current top " + top);
12188                    return false;
12189                }
12190                if (!top.nowVisible) {
12191                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12192                            + " is not visible");
12193                    return false;
12194                }
12195            }
12196            AssistUtils utils = new AssistUtils(mContext);
12197            return utils.showSessionForActiveService(args,
12198                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12199        } finally {
12200            Binder.restoreCallingIdentity(ident);
12201        }
12202    }
12203
12204    @Override
12205    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12206            Bundle receiverExtras,
12207            IBinder activityToken, boolean focused, boolean newSessionId) {
12208        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12209                activityToken, focused, newSessionId,
12210                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12211                != null;
12212    }
12213
12214    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12215            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12216            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12217        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12218                "enqueueAssistContext()");
12219        synchronized (this) {
12220            ActivityRecord activity = getFocusedStack().topActivity();
12221            if (activity == null) {
12222                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12223                return null;
12224            }
12225            if (activity.app == null || activity.app.thread == null) {
12226                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12227                return null;
12228            }
12229            if (focused) {
12230                if (activityToken != null) {
12231                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12232                    if (activity != caller) {
12233                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12234                                + " is not current top " + activity);
12235                        return null;
12236                    }
12237                }
12238            } else {
12239                activity = ActivityRecord.forTokenLocked(activityToken);
12240                if (activity == null) {
12241                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12242                            + " couldn't be found");
12243                    return null;
12244                }
12245            }
12246
12247            PendingAssistExtras pae;
12248            Bundle extras = new Bundle();
12249            if (args != null) {
12250                extras.putAll(args);
12251            }
12252            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12253            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12254            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12255                    userHandle);
12256            // Increment the sessionId if necessary
12257            if (newSessionId) {
12258                mViSessionId++;
12259            }
12260            try {
12261                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12262                        requestType, mViSessionId);
12263                mPendingAssistExtras.add(pae);
12264                mUiHandler.postDelayed(pae, timeout);
12265            } catch (RemoteException e) {
12266                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12267                return null;
12268            }
12269            return pae;
12270        }
12271    }
12272
12273    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12274        IResultReceiver receiver;
12275        synchronized (this) {
12276            mPendingAssistExtras.remove(pae);
12277            receiver = pae.receiver;
12278        }
12279        if (receiver != null) {
12280            // Caller wants result sent back to them.
12281            Bundle sendBundle = new Bundle();
12282            // At least return the receiver extras
12283            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12284                    pae.receiverExtras);
12285            try {
12286                pae.receiver.send(0, sendBundle);
12287            } catch (RemoteException e) {
12288            }
12289        }
12290    }
12291
12292    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12293        if (result != null) {
12294            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12295        }
12296        if (pae.hint != null) {
12297            pae.extras.putBoolean(pae.hint, true);
12298        }
12299    }
12300
12301    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12302            AssistContent content, Uri referrer) {
12303        PendingAssistExtras pae = (PendingAssistExtras)token;
12304        synchronized (pae) {
12305            pae.result = extras;
12306            pae.structure = structure;
12307            pae.content = content;
12308            if (referrer != null) {
12309                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12310            }
12311            pae.haveResult = true;
12312            pae.notifyAll();
12313            if (pae.intent == null && pae.receiver == null) {
12314                // Caller is just waiting for the result.
12315                return;
12316            }
12317        }
12318
12319        // We are now ready to launch the assist activity.
12320        IResultReceiver sendReceiver = null;
12321        Bundle sendBundle = null;
12322        synchronized (this) {
12323            buildAssistBundleLocked(pae, extras);
12324            boolean exists = mPendingAssistExtras.remove(pae);
12325            mUiHandler.removeCallbacks(pae);
12326            if (!exists) {
12327                // Timed out.
12328                return;
12329            }
12330            if ((sendReceiver=pae.receiver) != null) {
12331                // Caller wants result sent back to them.
12332                sendBundle = new Bundle();
12333                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12334                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12335                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12336                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12337                        pae.receiverExtras);
12338            }
12339        }
12340        if (sendReceiver != null) {
12341            try {
12342                sendReceiver.send(0, sendBundle);
12343            } catch (RemoteException e) {
12344            }
12345            return;
12346        }
12347
12348        long ident = Binder.clearCallingIdentity();
12349        try {
12350            pae.intent.replaceExtras(pae.extras);
12351            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12352                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12353                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12354            closeSystemDialogs("assist");
12355            try {
12356                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12357            } catch (ActivityNotFoundException e) {
12358                Slog.w(TAG, "No activity to handle assist action.", e);
12359            }
12360        } finally {
12361            Binder.restoreCallingIdentity(ident);
12362        }
12363    }
12364
12365    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12366            Bundle args) {
12367        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12368                true /* focused */, true /* newSessionId */,
12369                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12370    }
12371
12372    public void registerProcessObserver(IProcessObserver observer) {
12373        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12374                "registerProcessObserver()");
12375        synchronized (this) {
12376            mProcessObservers.register(observer);
12377        }
12378    }
12379
12380    @Override
12381    public void unregisterProcessObserver(IProcessObserver observer) {
12382        synchronized (this) {
12383            mProcessObservers.unregister(observer);
12384        }
12385    }
12386
12387    @Override
12388    public void registerUidObserver(IUidObserver observer, int which) {
12389        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12390                "registerUidObserver()");
12391        synchronized (this) {
12392            mUidObservers.register(observer, which);
12393        }
12394    }
12395
12396    @Override
12397    public void unregisterUidObserver(IUidObserver observer) {
12398        synchronized (this) {
12399            mUidObservers.unregister(observer);
12400        }
12401    }
12402
12403    @Override
12404    public boolean convertFromTranslucent(IBinder token) {
12405        final long origId = Binder.clearCallingIdentity();
12406        try {
12407            synchronized (this) {
12408                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12409                if (r == null) {
12410                    return false;
12411                }
12412                final boolean translucentChanged = r.changeWindowTranslucency(true);
12413                if (translucentChanged) {
12414                    r.task.stack.releaseBackgroundResources(r);
12415                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12416                }
12417                mWindowManager.setAppFullscreen(token, true);
12418                return translucentChanged;
12419            }
12420        } finally {
12421            Binder.restoreCallingIdentity(origId);
12422        }
12423    }
12424
12425    @Override
12426    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12427        final long origId = Binder.clearCallingIdentity();
12428        try {
12429            synchronized (this) {
12430                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12431                if (r == null) {
12432                    return false;
12433                }
12434                int index = r.task.mActivities.lastIndexOf(r);
12435                if (index > 0) {
12436                    ActivityRecord under = r.task.mActivities.get(index - 1);
12437                    under.returningOptions = options;
12438                }
12439                final boolean translucentChanged = r.changeWindowTranslucency(false);
12440                if (translucentChanged) {
12441                    r.task.stack.convertActivityToTranslucent(r);
12442                }
12443                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12444                mWindowManager.setAppFullscreen(token, false);
12445                return translucentChanged;
12446            }
12447        } finally {
12448            Binder.restoreCallingIdentity(origId);
12449        }
12450    }
12451
12452    @Override
12453    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12454        final long origId = Binder.clearCallingIdentity();
12455        try {
12456            synchronized (this) {
12457                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12458                if (r != null) {
12459                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12460                }
12461            }
12462            return false;
12463        } finally {
12464            Binder.restoreCallingIdentity(origId);
12465        }
12466    }
12467
12468    @Override
12469    public boolean isBackgroundVisibleBehind(IBinder token) {
12470        final long origId = Binder.clearCallingIdentity();
12471        try {
12472            synchronized (this) {
12473                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12474                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12475                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12476                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12477                return visible;
12478            }
12479        } finally {
12480            Binder.restoreCallingIdentity(origId);
12481        }
12482    }
12483
12484    @Override
12485    public ActivityOptions getActivityOptions(IBinder token) {
12486        final long origId = Binder.clearCallingIdentity();
12487        try {
12488            synchronized (this) {
12489                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12490                if (r != null) {
12491                    final ActivityOptions activityOptions = r.pendingOptions;
12492                    r.pendingOptions = null;
12493                    return activityOptions;
12494                }
12495                return null;
12496            }
12497        } finally {
12498            Binder.restoreCallingIdentity(origId);
12499        }
12500    }
12501
12502    @Override
12503    public void setImmersive(IBinder token, boolean immersive) {
12504        synchronized(this) {
12505            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12506            if (r == null) {
12507                throw new IllegalArgumentException();
12508            }
12509            r.immersive = immersive;
12510
12511            // update associated state if we're frontmost
12512            if (r == mFocusedActivity) {
12513                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12514                applyUpdateLockStateLocked(r);
12515            }
12516        }
12517    }
12518
12519    @Override
12520    public boolean isImmersive(IBinder token) {
12521        synchronized (this) {
12522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12523            if (r == null) {
12524                throw new IllegalArgumentException();
12525            }
12526            return r.immersive;
12527        }
12528    }
12529
12530    @Override
12531    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12532        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12533            throw new UnsupportedOperationException("VR mode not supported on this device!");
12534        }
12535
12536        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12537
12538        ActivityRecord r;
12539        synchronized (this) {
12540            r = ActivityRecord.isInStackLocked(token);
12541        }
12542
12543        if (r == null) {
12544            throw new IllegalArgumentException();
12545        }
12546
12547        int err;
12548        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12549                VrManagerInternal.NO_ERROR) {
12550            return err;
12551        }
12552
12553        synchronized(this) {
12554            r.requestedVrComponent = (enabled) ? packageName : null;
12555
12556            // Update associated state if this activity is currently focused
12557            if (r == mFocusedActivity) {
12558                applyUpdateVrModeLocked(r);
12559            }
12560            return 0;
12561        }
12562    }
12563
12564    @Override
12565    public boolean isVrModePackageEnabled(ComponentName packageName) {
12566        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12567            throw new UnsupportedOperationException("VR mode not supported on this device!");
12568        }
12569
12570        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12571
12572        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12573                VrManagerInternal.NO_ERROR;
12574    }
12575
12576    public boolean isTopActivityImmersive() {
12577        enforceNotIsolatedCaller("startActivity");
12578        synchronized (this) {
12579            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12580            return (r != null) ? r.immersive : false;
12581        }
12582    }
12583
12584    @Override
12585    public boolean isTopOfTask(IBinder token) {
12586        synchronized (this) {
12587            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12588            if (r == null) {
12589                throw new IllegalArgumentException();
12590            }
12591            return r.task.getTopActivity() == r;
12592        }
12593    }
12594
12595    public final void enterSafeMode() {
12596        synchronized(this) {
12597            // It only makes sense to do this before the system is ready
12598            // and started launching other packages.
12599            if (!mSystemReady) {
12600                try {
12601                    AppGlobals.getPackageManager().enterSafeMode();
12602                } catch (RemoteException e) {
12603                }
12604            }
12605
12606            mSafeMode = true;
12607        }
12608    }
12609
12610    public final void showSafeModeOverlay() {
12611        View v = LayoutInflater.from(mContext).inflate(
12612                com.android.internal.R.layout.safe_mode, null);
12613        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12614        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12615        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12616        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12617        lp.gravity = Gravity.BOTTOM | Gravity.START;
12618        lp.format = v.getBackground().getOpacity();
12619        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12620                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12621        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12622        ((WindowManager)mContext.getSystemService(
12623                Context.WINDOW_SERVICE)).addView(v, lp);
12624    }
12625
12626    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12627        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12628            return;
12629        }
12630        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12631        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12632        synchronized (stats) {
12633            if (mBatteryStatsService.isOnBattery()) {
12634                mBatteryStatsService.enforceCallingPermission();
12635                int MY_UID = Binder.getCallingUid();
12636                final int uid;
12637                if (sender == null) {
12638                    uid = sourceUid;
12639                } else {
12640                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12641                }
12642                BatteryStatsImpl.Uid.Pkg pkg =
12643                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12644                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12645                pkg.noteWakeupAlarmLocked(tag);
12646            }
12647        }
12648    }
12649
12650    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12651        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12652            return;
12653        }
12654        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12655        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12656        synchronized (stats) {
12657            mBatteryStatsService.enforceCallingPermission();
12658            int MY_UID = Binder.getCallingUid();
12659            final int uid;
12660            if (sender == null) {
12661                uid = sourceUid;
12662            } else {
12663                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12664            }
12665            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12666        }
12667    }
12668
12669    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12670        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12671            return;
12672        }
12673        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12674        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12675        synchronized (stats) {
12676            mBatteryStatsService.enforceCallingPermission();
12677            int MY_UID = Binder.getCallingUid();
12678            final int uid;
12679            if (sender == null) {
12680                uid = sourceUid;
12681            } else {
12682                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12683            }
12684            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12685        }
12686    }
12687
12688    public boolean killPids(int[] pids, String pReason, boolean secure) {
12689        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12690            throw new SecurityException("killPids only available to the system");
12691        }
12692        String reason = (pReason == null) ? "Unknown" : pReason;
12693        // XXX Note: don't acquire main activity lock here, because the window
12694        // manager calls in with its locks held.
12695
12696        boolean killed = false;
12697        synchronized (mPidsSelfLocked) {
12698            int worstType = 0;
12699            for (int i=0; i<pids.length; i++) {
12700                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12701                if (proc != null) {
12702                    int type = proc.setAdj;
12703                    if (type > worstType) {
12704                        worstType = type;
12705                    }
12706                }
12707            }
12708
12709            // If the worst oom_adj is somewhere in the cached proc LRU range,
12710            // then constrain it so we will kill all cached procs.
12711            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12712                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12713                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12714            }
12715
12716            // If this is not a secure call, don't let it kill processes that
12717            // are important.
12718            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12719                worstType = ProcessList.SERVICE_ADJ;
12720            }
12721
12722            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12723            for (int i=0; i<pids.length; i++) {
12724                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12725                if (proc == null) {
12726                    continue;
12727                }
12728                int adj = proc.setAdj;
12729                if (adj >= worstType && !proc.killedByAm) {
12730                    proc.kill(reason, true);
12731                    killed = true;
12732                }
12733            }
12734        }
12735        return killed;
12736    }
12737
12738    @Override
12739    public void killUid(int appId, int userId, String reason) {
12740        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12741        synchronized (this) {
12742            final long identity = Binder.clearCallingIdentity();
12743            try {
12744                killPackageProcessesLocked(null, appId, userId,
12745                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12746                        reason != null ? reason : "kill uid");
12747            } finally {
12748                Binder.restoreCallingIdentity(identity);
12749            }
12750        }
12751    }
12752
12753    @Override
12754    public boolean killProcessesBelowForeground(String reason) {
12755        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12756            throw new SecurityException("killProcessesBelowForeground() only available to system");
12757        }
12758
12759        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12760    }
12761
12762    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12763        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12764            throw new SecurityException("killProcessesBelowAdj() only available to system");
12765        }
12766
12767        boolean killed = false;
12768        synchronized (mPidsSelfLocked) {
12769            final int size = mPidsSelfLocked.size();
12770            for (int i = 0; i < size; i++) {
12771                final int pid = mPidsSelfLocked.keyAt(i);
12772                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12773                if (proc == null) continue;
12774
12775                final int adj = proc.setAdj;
12776                if (adj > belowAdj && !proc.killedByAm) {
12777                    proc.kill(reason, true);
12778                    killed = true;
12779                }
12780            }
12781        }
12782        return killed;
12783    }
12784
12785    @Override
12786    public void hang(final IBinder who, boolean allowRestart) {
12787        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12788                != PackageManager.PERMISSION_GRANTED) {
12789            throw new SecurityException("Requires permission "
12790                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12791        }
12792
12793        final IBinder.DeathRecipient death = new DeathRecipient() {
12794            @Override
12795            public void binderDied() {
12796                synchronized (this) {
12797                    notifyAll();
12798                }
12799            }
12800        };
12801
12802        try {
12803            who.linkToDeath(death, 0);
12804        } catch (RemoteException e) {
12805            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12806            return;
12807        }
12808
12809        synchronized (this) {
12810            Watchdog.getInstance().setAllowRestart(allowRestart);
12811            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12812            synchronized (death) {
12813                while (who.isBinderAlive()) {
12814                    try {
12815                        death.wait();
12816                    } catch (InterruptedException e) {
12817                    }
12818                }
12819            }
12820            Watchdog.getInstance().setAllowRestart(true);
12821        }
12822    }
12823
12824    @Override
12825    public void restart() {
12826        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12827                != PackageManager.PERMISSION_GRANTED) {
12828            throw new SecurityException("Requires permission "
12829                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12830        }
12831
12832        Log.i(TAG, "Sending shutdown broadcast...");
12833
12834        BroadcastReceiver br = new BroadcastReceiver() {
12835            @Override public void onReceive(Context context, Intent intent) {
12836                // Now the broadcast is done, finish up the low-level shutdown.
12837                Log.i(TAG, "Shutting down activity manager...");
12838                shutdown(10000);
12839                Log.i(TAG, "Shutdown complete, restarting!");
12840                Process.killProcess(Process.myPid());
12841                System.exit(10);
12842            }
12843        };
12844
12845        // First send the high-level shut down broadcast.
12846        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12847        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12848        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12849        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12850        mContext.sendOrderedBroadcastAsUser(intent,
12851                UserHandle.ALL, null, br, mHandler, 0, null, null);
12852        */
12853        br.onReceive(mContext, intent);
12854    }
12855
12856    private long getLowRamTimeSinceIdle(long now) {
12857        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12858    }
12859
12860    @Override
12861    public void performIdleMaintenance() {
12862        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12863                != PackageManager.PERMISSION_GRANTED) {
12864            throw new SecurityException("Requires permission "
12865                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12866        }
12867
12868        synchronized (this) {
12869            final long now = SystemClock.uptimeMillis();
12870            final long timeSinceLastIdle = now - mLastIdleTime;
12871            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12872            mLastIdleTime = now;
12873            mLowRamTimeSinceLastIdle = 0;
12874            if (mLowRamStartTime != 0) {
12875                mLowRamStartTime = now;
12876            }
12877
12878            StringBuilder sb = new StringBuilder(128);
12879            sb.append("Idle maintenance over ");
12880            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12881            sb.append(" low RAM for ");
12882            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12883            Slog.i(TAG, sb.toString());
12884
12885            // If at least 1/3 of our time since the last idle period has been spent
12886            // with RAM low, then we want to kill processes.
12887            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12888
12889            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12890                ProcessRecord proc = mLruProcesses.get(i);
12891                if (proc.notCachedSinceIdle) {
12892                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12893                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12894                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12895                        if (doKilling && proc.initialIdlePss != 0
12896                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12897                            sb = new StringBuilder(128);
12898                            sb.append("Kill");
12899                            sb.append(proc.processName);
12900                            sb.append(" in idle maint: pss=");
12901                            sb.append(proc.lastPss);
12902                            sb.append(", swapPss=");
12903                            sb.append(proc.lastSwapPss);
12904                            sb.append(", initialPss=");
12905                            sb.append(proc.initialIdlePss);
12906                            sb.append(", period=");
12907                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12908                            sb.append(", lowRamPeriod=");
12909                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12910                            Slog.wtfQuiet(TAG, sb.toString());
12911                            proc.kill("idle maint (pss " + proc.lastPss
12912                                    + " from " + proc.initialIdlePss + ")", true);
12913                        }
12914                    }
12915                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12916                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12917                    proc.notCachedSinceIdle = true;
12918                    proc.initialIdlePss = 0;
12919                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12920                            mTestPssMode, isSleepingLocked(), now);
12921                }
12922            }
12923
12924            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12925            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12926        }
12927    }
12928
12929    @Override
12930    public void sendIdleJobTrigger() {
12931        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12932                != PackageManager.PERMISSION_GRANTED) {
12933            throw new SecurityException("Requires permission "
12934                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12935        }
12936
12937        final long ident = Binder.clearCallingIdentity();
12938        try {
12939            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12940                    .setPackage("android")
12941                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12942            broadcastIntent(null, intent, null, null, 0, null, null, null,
12943                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12944        } finally {
12945            Binder.restoreCallingIdentity(ident);
12946        }
12947    }
12948
12949    private void retrieveSettings() {
12950        final ContentResolver resolver = mContext.getContentResolver();
12951        final boolean freeformWindowManagement =
12952                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12953                        || Settings.Global.getInt(
12954                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12955        final boolean supportsPictureInPicture =
12956                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12957
12958        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12959        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12960        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12961        final boolean alwaysFinishActivities =
12962                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12963        final boolean lenientBackgroundCheck =
12964                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12965        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12966        final boolean forceResizable = Settings.Global.getInt(
12967                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12968        final boolean supportsLeanbackOnly =
12969                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12970
12971        // Transfer any global setting for forcing RTL layout, into a System Property
12972        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12973
12974        final Configuration configuration = new Configuration();
12975        Settings.System.getConfiguration(resolver, configuration);
12976        if (forceRtl) {
12977            // This will take care of setting the correct layout direction flags
12978            configuration.setLayoutDirection(configuration.locale);
12979        }
12980
12981        synchronized (this) {
12982            mDebugApp = mOrigDebugApp = debugApp;
12983            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12984            mAlwaysFinishActivities = alwaysFinishActivities;
12985            mLenientBackgroundCheck = lenientBackgroundCheck;
12986            mSupportsLeanbackOnly = supportsLeanbackOnly;
12987            mForceResizableActivities = forceResizable;
12988            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12989            if (supportsMultiWindow || forceResizable) {
12990                mSupportsMultiWindow = true;
12991                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12992                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12993            } else {
12994                mSupportsMultiWindow = false;
12995                mSupportsFreeformWindowManagement = false;
12996                mSupportsPictureInPicture = false;
12997            }
12998            // This happens before any activities are started, so we can
12999            // change mConfiguration in-place.
13000            updateConfigurationLocked(configuration, null, true);
13001            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13002                    "Initial config: " + mConfiguration);
13003
13004            // Load resources only after the current configuration has been set.
13005            final Resources res = mContext.getResources();
13006            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13007            mThumbnailWidth = res.getDimensionPixelSize(
13008                    com.android.internal.R.dimen.thumbnail_width);
13009            mThumbnailHeight = res.getDimensionPixelSize(
13010                    com.android.internal.R.dimen.thumbnail_height);
13011            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13012                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13013            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13014                    com.android.internal.R.string.config_appsNotReportingCrashes));
13015            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13016                mFullscreenThumbnailScale = (float) res
13017                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13018                    (float) mConfiguration.screenWidthDp;
13019            } else {
13020                mFullscreenThumbnailScale = res.getFraction(
13021                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13022            }
13023        }
13024    }
13025
13026    public boolean testIsSystemReady() {
13027        // no need to synchronize(this) just to read & return the value
13028        return mSystemReady;
13029    }
13030
13031    public void systemReady(final Runnable goingCallback) {
13032        synchronized(this) {
13033            if (mSystemReady) {
13034                // If we're done calling all the receivers, run the next "boot phase" passed in
13035                // by the SystemServer
13036                if (goingCallback != null) {
13037                    goingCallback.run();
13038                }
13039                return;
13040            }
13041
13042            mLocalDeviceIdleController
13043                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13044
13045            // Make sure we have the current profile info, since it is needed for security checks.
13046            mUserController.onSystemReady();
13047            mRecentTasks.onSystemReadyLocked();
13048            mAppOpsService.systemReady();
13049            mSystemReady = true;
13050        }
13051
13052        ArrayList<ProcessRecord> procsToKill = null;
13053        synchronized(mPidsSelfLocked) {
13054            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13055                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13056                if (!isAllowedWhileBooting(proc.info)){
13057                    if (procsToKill == null) {
13058                        procsToKill = new ArrayList<ProcessRecord>();
13059                    }
13060                    procsToKill.add(proc);
13061                }
13062            }
13063        }
13064
13065        synchronized(this) {
13066            if (procsToKill != null) {
13067                for (int i=procsToKill.size()-1; i>=0; i--) {
13068                    ProcessRecord proc = procsToKill.get(i);
13069                    Slog.i(TAG, "Removing system update proc: " + proc);
13070                    removeProcessLocked(proc, true, false, "system update done");
13071                }
13072            }
13073
13074            // Now that we have cleaned up any update processes, we
13075            // are ready to start launching real processes and know that
13076            // we won't trample on them any more.
13077            mProcessesReady = true;
13078        }
13079
13080        Slog.i(TAG, "System now ready");
13081        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13082            SystemClock.uptimeMillis());
13083
13084        synchronized(this) {
13085            // Make sure we have no pre-ready processes sitting around.
13086
13087            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13088                ResolveInfo ri = mContext.getPackageManager()
13089                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13090                                STOCK_PM_FLAGS);
13091                CharSequence errorMsg = null;
13092                if (ri != null) {
13093                    ActivityInfo ai = ri.activityInfo;
13094                    ApplicationInfo app = ai.applicationInfo;
13095                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13096                        mTopAction = Intent.ACTION_FACTORY_TEST;
13097                        mTopData = null;
13098                        mTopComponent = new ComponentName(app.packageName,
13099                                ai.name);
13100                    } else {
13101                        errorMsg = mContext.getResources().getText(
13102                                com.android.internal.R.string.factorytest_not_system);
13103                    }
13104                } else {
13105                    errorMsg = mContext.getResources().getText(
13106                            com.android.internal.R.string.factorytest_no_action);
13107                }
13108                if (errorMsg != null) {
13109                    mTopAction = null;
13110                    mTopData = null;
13111                    mTopComponent = null;
13112                    Message msg = Message.obtain();
13113                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13114                    msg.getData().putCharSequence("msg", errorMsg);
13115                    mUiHandler.sendMessage(msg);
13116                }
13117            }
13118        }
13119
13120        retrieveSettings();
13121        final int currentUserId;
13122        synchronized (this) {
13123            currentUserId = mUserController.getCurrentUserIdLocked();
13124            readGrantedUriPermissionsLocked();
13125        }
13126
13127        if (goingCallback != null) goingCallback.run();
13128
13129        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13130                Integer.toString(currentUserId), currentUserId);
13131        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13132                Integer.toString(currentUserId), currentUserId);
13133        mSystemServiceManager.startUser(currentUserId);
13134
13135        synchronized (this) {
13136            // Only start up encryption-aware persistent apps; once user is
13137            // unlocked we'll come back around and start unaware apps
13138            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13139
13140            // Start up initial activity.
13141            mBooting = true;
13142            // Enable home activity for system user, so that the system can always boot
13143            if (UserManager.isSplitSystemUser()) {
13144                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13145                try {
13146                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13147                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13148                            UserHandle.USER_SYSTEM);
13149                } catch (RemoteException e) {
13150                    throw e.rethrowAsRuntimeException();
13151                }
13152            }
13153            startHomeActivityLocked(currentUserId, "systemReady");
13154
13155            try {
13156                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13157                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13158                            + " data partition or your device will be unstable.");
13159                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13160                }
13161            } catch (RemoteException e) {
13162            }
13163
13164            if (!Build.isBuildConsistent()) {
13165                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13166                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13167            }
13168
13169            long ident = Binder.clearCallingIdentity();
13170            try {
13171                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13172                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13173                        | Intent.FLAG_RECEIVER_FOREGROUND);
13174                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13175                broadcastIntentLocked(null, null, intent,
13176                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13177                        null, false, false, MY_PID, Process.SYSTEM_UID,
13178                        currentUserId);
13179                intent = new Intent(Intent.ACTION_USER_STARTING);
13180                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13181                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13182                broadcastIntentLocked(null, null, intent,
13183                        null, new IIntentReceiver.Stub() {
13184                            @Override
13185                            public void performReceive(Intent intent, int resultCode, String data,
13186                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13187                                    throws RemoteException {
13188                            }
13189                        }, 0, null, null,
13190                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13191                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13192            } catch (Throwable t) {
13193                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13194            } finally {
13195                Binder.restoreCallingIdentity(ident);
13196            }
13197            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13198            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13199        }
13200    }
13201
13202    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13203        synchronized (this) {
13204            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13205        }
13206    }
13207
13208    void skipCurrentReceiverLocked(ProcessRecord app) {
13209        for (BroadcastQueue queue : mBroadcastQueues) {
13210            queue.skipCurrentReceiverLocked(app);
13211        }
13212    }
13213
13214    /**
13215     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13216     * The application process will exit immediately after this call returns.
13217     * @param app object of the crashing app, null for the system server
13218     * @param crashInfo describing the exception
13219     */
13220    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13221        ProcessRecord r = findAppProcess(app, "Crash");
13222        final String processName = app == null ? "system_server"
13223                : (r == null ? "unknown" : r.processName);
13224
13225        handleApplicationCrashInner("crash", r, processName, crashInfo);
13226    }
13227
13228    /* Native crash reporting uses this inner version because it needs to be somewhat
13229     * decoupled from the AM-managed cleanup lifecycle
13230     */
13231    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13232            ApplicationErrorReport.CrashInfo crashInfo) {
13233        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13234                UserHandle.getUserId(Binder.getCallingUid()), processName,
13235                r == null ? -1 : r.info.flags,
13236                crashInfo.exceptionClassName,
13237                crashInfo.exceptionMessage,
13238                crashInfo.throwFileName,
13239                crashInfo.throwLineNumber);
13240
13241        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13242
13243        mAppErrors.crashApplication(r, crashInfo);
13244    }
13245
13246    public void handleApplicationStrictModeViolation(
13247            IBinder app,
13248            int violationMask,
13249            StrictMode.ViolationInfo info) {
13250        ProcessRecord r = findAppProcess(app, "StrictMode");
13251        if (r == null) {
13252            return;
13253        }
13254
13255        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13256            Integer stackFingerprint = info.hashCode();
13257            boolean logIt = true;
13258            synchronized (mAlreadyLoggedViolatedStacks) {
13259                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13260                    logIt = false;
13261                    // TODO: sub-sample into EventLog for these, with
13262                    // the info.durationMillis?  Then we'd get
13263                    // the relative pain numbers, without logging all
13264                    // the stack traces repeatedly.  We'd want to do
13265                    // likewise in the client code, which also does
13266                    // dup suppression, before the Binder call.
13267                } else {
13268                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13269                        mAlreadyLoggedViolatedStacks.clear();
13270                    }
13271                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13272                }
13273            }
13274            if (logIt) {
13275                logStrictModeViolationToDropBox(r, info);
13276            }
13277        }
13278
13279        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13280            AppErrorResult result = new AppErrorResult();
13281            synchronized (this) {
13282                final long origId = Binder.clearCallingIdentity();
13283
13284                Message msg = Message.obtain();
13285                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13286                HashMap<String, Object> data = new HashMap<String, Object>();
13287                data.put("result", result);
13288                data.put("app", r);
13289                data.put("violationMask", violationMask);
13290                data.put("info", info);
13291                msg.obj = data;
13292                mUiHandler.sendMessage(msg);
13293
13294                Binder.restoreCallingIdentity(origId);
13295            }
13296            int res = result.get();
13297            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13298        }
13299    }
13300
13301    // Depending on the policy in effect, there could be a bunch of
13302    // these in quick succession so we try to batch these together to
13303    // minimize disk writes, number of dropbox entries, and maximize
13304    // compression, by having more fewer, larger records.
13305    private void logStrictModeViolationToDropBox(
13306            ProcessRecord process,
13307            StrictMode.ViolationInfo info) {
13308        if (info == null) {
13309            return;
13310        }
13311        final boolean isSystemApp = process == null ||
13312                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13313                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13314        final String processName = process == null ? "unknown" : process.processName;
13315        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13316        final DropBoxManager dbox = (DropBoxManager)
13317                mContext.getSystemService(Context.DROPBOX_SERVICE);
13318
13319        // Exit early if the dropbox isn't configured to accept this report type.
13320        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13321
13322        boolean bufferWasEmpty;
13323        boolean needsFlush;
13324        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13325        synchronized (sb) {
13326            bufferWasEmpty = sb.length() == 0;
13327            appendDropBoxProcessHeaders(process, processName, sb);
13328            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13329            sb.append("System-App: ").append(isSystemApp).append("\n");
13330            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13331            if (info.violationNumThisLoop != 0) {
13332                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13333            }
13334            if (info.numAnimationsRunning != 0) {
13335                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13336            }
13337            if (info.broadcastIntentAction != null) {
13338                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13339            }
13340            if (info.durationMillis != -1) {
13341                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13342            }
13343            if (info.numInstances != -1) {
13344                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13345            }
13346            if (info.tags != null) {
13347                for (String tag : info.tags) {
13348                    sb.append("Span-Tag: ").append(tag).append("\n");
13349                }
13350            }
13351            sb.append("\n");
13352            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13353                sb.append(info.crashInfo.stackTrace);
13354                sb.append("\n");
13355            }
13356            if (info.message != null) {
13357                sb.append(info.message);
13358                sb.append("\n");
13359            }
13360
13361            // Only buffer up to ~64k.  Various logging bits truncate
13362            // things at 128k.
13363            needsFlush = (sb.length() > 64 * 1024);
13364        }
13365
13366        // Flush immediately if the buffer's grown too large, or this
13367        // is a non-system app.  Non-system apps are isolated with a
13368        // different tag & policy and not batched.
13369        //
13370        // Batching is useful during internal testing with
13371        // StrictMode settings turned up high.  Without batching,
13372        // thousands of separate files could be created on boot.
13373        if (!isSystemApp || needsFlush) {
13374            new Thread("Error dump: " + dropboxTag) {
13375                @Override
13376                public void run() {
13377                    String report;
13378                    synchronized (sb) {
13379                        report = sb.toString();
13380                        sb.delete(0, sb.length());
13381                        sb.trimToSize();
13382                    }
13383                    if (report.length() != 0) {
13384                        dbox.addText(dropboxTag, report);
13385                    }
13386                }
13387            }.start();
13388            return;
13389        }
13390
13391        // System app batching:
13392        if (!bufferWasEmpty) {
13393            // An existing dropbox-writing thread is outstanding, so
13394            // we don't need to start it up.  The existing thread will
13395            // catch the buffer appends we just did.
13396            return;
13397        }
13398
13399        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13400        // (After this point, we shouldn't access AMS internal data structures.)
13401        new Thread("Error dump: " + dropboxTag) {
13402            @Override
13403            public void run() {
13404                // 5 second sleep to let stacks arrive and be batched together
13405                try {
13406                    Thread.sleep(5000);  // 5 seconds
13407                } catch (InterruptedException e) {}
13408
13409                String errorReport;
13410                synchronized (mStrictModeBuffer) {
13411                    errorReport = mStrictModeBuffer.toString();
13412                    if (errorReport.length() == 0) {
13413                        return;
13414                    }
13415                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13416                    mStrictModeBuffer.trimToSize();
13417                }
13418                dbox.addText(dropboxTag, errorReport);
13419            }
13420        }.start();
13421    }
13422
13423    /**
13424     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13425     * @param app object of the crashing app, null for the system server
13426     * @param tag reported by the caller
13427     * @param system whether this wtf is coming from the system
13428     * @param crashInfo describing the context of the error
13429     * @return true if the process should exit immediately (WTF is fatal)
13430     */
13431    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13432            final ApplicationErrorReport.CrashInfo crashInfo) {
13433        final int callingUid = Binder.getCallingUid();
13434        final int callingPid = Binder.getCallingPid();
13435
13436        if (system) {
13437            // If this is coming from the system, we could very well have low-level
13438            // system locks held, so we want to do this all asynchronously.  And we
13439            // never want this to become fatal, so there is that too.
13440            mHandler.post(new Runnable() {
13441                @Override public void run() {
13442                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13443                }
13444            });
13445            return false;
13446        }
13447
13448        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13449                crashInfo);
13450
13451        if (r != null && r.pid != Process.myPid() &&
13452                Settings.Global.getInt(mContext.getContentResolver(),
13453                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13454            mAppErrors.crashApplication(r, crashInfo);
13455            return true;
13456        } else {
13457            return false;
13458        }
13459    }
13460
13461    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13462            final ApplicationErrorReport.CrashInfo crashInfo) {
13463        final ProcessRecord r = findAppProcess(app, "WTF");
13464        final String processName = app == null ? "system_server"
13465                : (r == null ? "unknown" : r.processName);
13466
13467        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13468                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13469
13470        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13471
13472        return r;
13473    }
13474
13475    /**
13476     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13477     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13478     */
13479    private ProcessRecord findAppProcess(IBinder app, String reason) {
13480        if (app == null) {
13481            return null;
13482        }
13483
13484        synchronized (this) {
13485            final int NP = mProcessNames.getMap().size();
13486            for (int ip=0; ip<NP; ip++) {
13487                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13488                final int NA = apps.size();
13489                for (int ia=0; ia<NA; ia++) {
13490                    ProcessRecord p = apps.valueAt(ia);
13491                    if (p.thread != null && p.thread.asBinder() == app) {
13492                        return p;
13493                    }
13494                }
13495            }
13496
13497            Slog.w(TAG, "Can't find mystery application for " + reason
13498                    + " from pid=" + Binder.getCallingPid()
13499                    + " uid=" + Binder.getCallingUid() + ": " + app);
13500            return null;
13501        }
13502    }
13503
13504    /**
13505     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13506     * to append various headers to the dropbox log text.
13507     */
13508    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13509            StringBuilder sb) {
13510        // Watchdog thread ends up invoking this function (with
13511        // a null ProcessRecord) to add the stack file to dropbox.
13512        // Do not acquire a lock on this (am) in such cases, as it
13513        // could cause a potential deadlock, if and when watchdog
13514        // is invoked due to unavailability of lock on am and it
13515        // would prevent watchdog from killing system_server.
13516        if (process == null) {
13517            sb.append("Process: ").append(processName).append("\n");
13518            return;
13519        }
13520        // Note: ProcessRecord 'process' is guarded by the service
13521        // instance.  (notably process.pkgList, which could otherwise change
13522        // concurrently during execution of this method)
13523        synchronized (this) {
13524            sb.append("Process: ").append(processName).append("\n");
13525            int flags = process.info.flags;
13526            IPackageManager pm = AppGlobals.getPackageManager();
13527            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13528            for (int ip=0; ip<process.pkgList.size(); ip++) {
13529                String pkg = process.pkgList.keyAt(ip);
13530                sb.append("Package: ").append(pkg);
13531                try {
13532                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13533                    if (pi != null) {
13534                        sb.append(" v").append(pi.versionCode);
13535                        if (pi.versionName != null) {
13536                            sb.append(" (").append(pi.versionName).append(")");
13537                        }
13538                    }
13539                } catch (RemoteException e) {
13540                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13541                }
13542                sb.append("\n");
13543            }
13544        }
13545    }
13546
13547    private static String processClass(ProcessRecord process) {
13548        if (process == null || process.pid == MY_PID) {
13549            return "system_server";
13550        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13551            return "system_app";
13552        } else {
13553            return "data_app";
13554        }
13555    }
13556
13557    private volatile long mWtfClusterStart;
13558    private volatile int mWtfClusterCount;
13559
13560    /**
13561     * Write a description of an error (crash, WTF, ANR) to the drop box.
13562     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13563     * @param process which caused the error, null means the system server
13564     * @param activity which triggered the error, null if unknown
13565     * @param parent activity related to the error, null if unknown
13566     * @param subject line related to the error, null if absent
13567     * @param report in long form describing the error, null if absent
13568     * @param logFile to include in the report, null if none
13569     * @param crashInfo giving an application stack trace, null if absent
13570     */
13571    public void addErrorToDropBox(String eventType,
13572            ProcessRecord process, String processName, ActivityRecord activity,
13573            ActivityRecord parent, String subject,
13574            final String report, final File logFile,
13575            final ApplicationErrorReport.CrashInfo crashInfo) {
13576        // NOTE -- this must never acquire the ActivityManagerService lock,
13577        // otherwise the watchdog may be prevented from resetting the system.
13578
13579        final String dropboxTag = processClass(process) + "_" + eventType;
13580        final DropBoxManager dbox = (DropBoxManager)
13581                mContext.getSystemService(Context.DROPBOX_SERVICE);
13582
13583        // Exit early if the dropbox isn't configured to accept this report type.
13584        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13585
13586        // Rate-limit how often we're willing to do the heavy lifting below to
13587        // collect and record logs; currently 5 logs per 10 second period.
13588        final long now = SystemClock.elapsedRealtime();
13589        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13590            mWtfClusterStart = now;
13591            mWtfClusterCount = 1;
13592        } else {
13593            if (mWtfClusterCount++ >= 5) return;
13594        }
13595
13596        final StringBuilder sb = new StringBuilder(1024);
13597        appendDropBoxProcessHeaders(process, processName, sb);
13598        if (process != null) {
13599            sb.append("Foreground: ")
13600                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13601                    .append("\n");
13602        }
13603        if (activity != null) {
13604            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13605        }
13606        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13607            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13608        }
13609        if (parent != null && parent != activity) {
13610            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13611        }
13612        if (subject != null) {
13613            sb.append("Subject: ").append(subject).append("\n");
13614        }
13615        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13616        if (Debug.isDebuggerConnected()) {
13617            sb.append("Debugger: Connected\n");
13618        }
13619        sb.append("\n");
13620
13621        // Do the rest in a worker thread to avoid blocking the caller on I/O
13622        // (After this point, we shouldn't access AMS internal data structures.)
13623        Thread worker = new Thread("Error dump: " + dropboxTag) {
13624            @Override
13625            public void run() {
13626                if (report != null) {
13627                    sb.append(report);
13628                }
13629                if (logFile != null) {
13630                    try {
13631                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13632                                    "\n\n[[TRUNCATED]]"));
13633                    } catch (IOException e) {
13634                        Slog.e(TAG, "Error reading " + logFile, e);
13635                    }
13636                }
13637                if (crashInfo != null && crashInfo.stackTrace != null) {
13638                    sb.append(crashInfo.stackTrace);
13639                }
13640
13641                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13642                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13643                if (lines > 0) {
13644                    sb.append("\n");
13645
13646                    // Merge several logcat streams, and take the last N lines
13647                    InputStreamReader input = null;
13648                    try {
13649                        java.lang.Process logcat = new ProcessBuilder(
13650                                "/system/bin/timeout", "-k", "15s", "10s",
13651                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13652                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13653                                        .redirectErrorStream(true).start();
13654
13655                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13656                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13657                        input = new InputStreamReader(logcat.getInputStream());
13658
13659                        int num;
13660                        char[] buf = new char[8192];
13661                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13662                    } catch (IOException e) {
13663                        Slog.e(TAG, "Error running logcat", e);
13664                    } finally {
13665                        if (input != null) try { input.close(); } catch (IOException e) {}
13666                    }
13667                }
13668
13669                dbox.addText(dropboxTag, sb.toString());
13670            }
13671        };
13672
13673        if (process == null) {
13674            // If process is null, we are being called from some internal code
13675            // and may be about to die -- run this synchronously.
13676            worker.run();
13677        } else {
13678            worker.start();
13679        }
13680    }
13681
13682    @Override
13683    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13684        enforceNotIsolatedCaller("getProcessesInErrorState");
13685        // assume our apps are happy - lazy create the list
13686        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13687
13688        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13689                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13690        int userId = UserHandle.getUserId(Binder.getCallingUid());
13691
13692        synchronized (this) {
13693
13694            // iterate across all processes
13695            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13696                ProcessRecord app = mLruProcesses.get(i);
13697                if (!allUsers && app.userId != userId) {
13698                    continue;
13699                }
13700                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13701                    // This one's in trouble, so we'll generate a report for it
13702                    // crashes are higher priority (in case there's a crash *and* an anr)
13703                    ActivityManager.ProcessErrorStateInfo report = null;
13704                    if (app.crashing) {
13705                        report = app.crashingReport;
13706                    } else if (app.notResponding) {
13707                        report = app.notRespondingReport;
13708                    }
13709
13710                    if (report != null) {
13711                        if (errList == null) {
13712                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13713                        }
13714                        errList.add(report);
13715                    } else {
13716                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13717                                " crashing = " + app.crashing +
13718                                " notResponding = " + app.notResponding);
13719                    }
13720                }
13721            }
13722        }
13723
13724        return errList;
13725    }
13726
13727    static int procStateToImportance(int procState, int memAdj,
13728            ActivityManager.RunningAppProcessInfo currApp) {
13729        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13730        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13731            currApp.lru = memAdj;
13732        } else {
13733            currApp.lru = 0;
13734        }
13735        return imp;
13736    }
13737
13738    private void fillInProcMemInfo(ProcessRecord app,
13739            ActivityManager.RunningAppProcessInfo outInfo) {
13740        outInfo.pid = app.pid;
13741        outInfo.uid = app.info.uid;
13742        if (mHeavyWeightProcess == app) {
13743            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13744        }
13745        if (app.persistent) {
13746            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13747        }
13748        if (app.activities.size() > 0) {
13749            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13750        }
13751        outInfo.lastTrimLevel = app.trimMemoryLevel;
13752        int adj = app.curAdj;
13753        int procState = app.curProcState;
13754        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13755        outInfo.importanceReasonCode = app.adjTypeCode;
13756        outInfo.processState = app.curProcState;
13757    }
13758
13759    @Override
13760    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13761        enforceNotIsolatedCaller("getRunningAppProcesses");
13762
13763        final int callingUid = Binder.getCallingUid();
13764
13765        // Lazy instantiation of list
13766        List<ActivityManager.RunningAppProcessInfo> runList = null;
13767        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13768                callingUid) == PackageManager.PERMISSION_GRANTED;
13769        final int userId = UserHandle.getUserId(callingUid);
13770        final boolean allUids = isGetTasksAllowed(
13771                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13772
13773        synchronized (this) {
13774            // Iterate across all processes
13775            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13776                ProcessRecord app = mLruProcesses.get(i);
13777                if ((!allUsers && app.userId != userId)
13778                        || (!allUids && app.uid != callingUid)) {
13779                    continue;
13780                }
13781                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13782                    // Generate process state info for running application
13783                    ActivityManager.RunningAppProcessInfo currApp =
13784                        new ActivityManager.RunningAppProcessInfo(app.processName,
13785                                app.pid, app.getPackageList());
13786                    fillInProcMemInfo(app, currApp);
13787                    if (app.adjSource instanceof ProcessRecord) {
13788                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13789                        currApp.importanceReasonImportance =
13790                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13791                                        app.adjSourceProcState);
13792                    } else if (app.adjSource instanceof ActivityRecord) {
13793                        ActivityRecord r = (ActivityRecord)app.adjSource;
13794                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13795                    }
13796                    if (app.adjTarget instanceof ComponentName) {
13797                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13798                    }
13799                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13800                    //        + " lru=" + currApp.lru);
13801                    if (runList == null) {
13802                        runList = new ArrayList<>();
13803                    }
13804                    runList.add(currApp);
13805                }
13806            }
13807        }
13808        return runList;
13809    }
13810
13811    @Override
13812    public List<ApplicationInfo> getRunningExternalApplications() {
13813        enforceNotIsolatedCaller("getRunningExternalApplications");
13814        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13815        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13816        if (runningApps != null && runningApps.size() > 0) {
13817            Set<String> extList = new HashSet<String>();
13818            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13819                if (app.pkgList != null) {
13820                    for (String pkg : app.pkgList) {
13821                        extList.add(pkg);
13822                    }
13823                }
13824            }
13825            IPackageManager pm = AppGlobals.getPackageManager();
13826            for (String pkg : extList) {
13827                try {
13828                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13829                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13830                        retList.add(info);
13831                    }
13832                } catch (RemoteException e) {
13833                }
13834            }
13835        }
13836        return retList;
13837    }
13838
13839    @Override
13840    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13841        enforceNotIsolatedCaller("getMyMemoryState");
13842        synchronized (this) {
13843            ProcessRecord proc;
13844            synchronized (mPidsSelfLocked) {
13845                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13846            }
13847            fillInProcMemInfo(proc, outInfo);
13848        }
13849    }
13850
13851    @Override
13852    public int getMemoryTrimLevel() {
13853        enforceNotIsolatedCaller("getMyMemoryState");
13854        synchronized (this) {
13855            return mLastMemoryLevel;
13856        }
13857    }
13858
13859    @Override
13860    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13861            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13862        (new ActivityManagerShellCommand(this, false)).exec(
13863                this, in, out, err, args, resultReceiver);
13864    }
13865
13866    @Override
13867    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13868        if (checkCallingPermission(android.Manifest.permission.DUMP)
13869                != PackageManager.PERMISSION_GRANTED) {
13870            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13871                    + Binder.getCallingPid()
13872                    + ", uid=" + Binder.getCallingUid()
13873                    + " without permission "
13874                    + android.Manifest.permission.DUMP);
13875            return;
13876        }
13877
13878        boolean dumpAll = false;
13879        boolean dumpClient = false;
13880        boolean dumpCheckin = false;
13881        boolean dumpCheckinFormat = false;
13882        String dumpPackage = null;
13883
13884        int opti = 0;
13885        while (opti < args.length) {
13886            String opt = args[opti];
13887            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13888                break;
13889            }
13890            opti++;
13891            if ("-a".equals(opt)) {
13892                dumpAll = true;
13893            } else if ("-c".equals(opt)) {
13894                dumpClient = true;
13895            } else if ("-p".equals(opt)) {
13896                if (opti < args.length) {
13897                    dumpPackage = args[opti];
13898                    opti++;
13899                } else {
13900                    pw.println("Error: -p option requires package argument");
13901                    return;
13902                }
13903                dumpClient = true;
13904            } else if ("--checkin".equals(opt)) {
13905                dumpCheckin = dumpCheckinFormat = true;
13906            } else if ("-C".equals(opt)) {
13907                dumpCheckinFormat = true;
13908            } else if ("-h".equals(opt)) {
13909                ActivityManagerShellCommand.dumpHelp(pw, true);
13910                return;
13911            } else {
13912                pw.println("Unknown argument: " + opt + "; use -h for help");
13913            }
13914        }
13915
13916        long origId = Binder.clearCallingIdentity();
13917        boolean more = false;
13918        // Is the caller requesting to dump a particular piece of data?
13919        if (opti < args.length) {
13920            String cmd = args[opti];
13921            opti++;
13922            if ("activities".equals(cmd) || "a".equals(cmd)) {
13923                synchronized (this) {
13924                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13925                }
13926            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13927                synchronized (this) {
13928                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13929                }
13930            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13931                String[] newArgs;
13932                String name;
13933                if (opti >= args.length) {
13934                    name = null;
13935                    newArgs = EMPTY_STRING_ARRAY;
13936                } else {
13937                    dumpPackage = args[opti];
13938                    opti++;
13939                    newArgs = new String[args.length - opti];
13940                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13941                            args.length - opti);
13942                }
13943                synchronized (this) {
13944                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13945                }
13946            } else if ("broadcast-stats".equals(cmd)) {
13947                String[] newArgs;
13948                String name;
13949                if (opti >= args.length) {
13950                    name = null;
13951                    newArgs = EMPTY_STRING_ARRAY;
13952                } else {
13953                    dumpPackage = args[opti];
13954                    opti++;
13955                    newArgs = new String[args.length - opti];
13956                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13957                            args.length - opti);
13958                }
13959                synchronized (this) {
13960                    if (dumpCheckinFormat) {
13961                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13962                                dumpPackage);
13963                    } else {
13964                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13965                    }
13966                }
13967            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13968                String[] newArgs;
13969                String name;
13970                if (opti >= args.length) {
13971                    name = null;
13972                    newArgs = EMPTY_STRING_ARRAY;
13973                } else {
13974                    dumpPackage = args[opti];
13975                    opti++;
13976                    newArgs = new String[args.length - opti];
13977                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13978                            args.length - opti);
13979                }
13980                synchronized (this) {
13981                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13982                }
13983            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13984                String[] newArgs;
13985                String name;
13986                if (opti >= args.length) {
13987                    name = null;
13988                    newArgs = EMPTY_STRING_ARRAY;
13989                } else {
13990                    dumpPackage = args[opti];
13991                    opti++;
13992                    newArgs = new String[args.length - opti];
13993                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13994                            args.length - opti);
13995                }
13996                synchronized (this) {
13997                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13998                }
13999            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14000                synchronized (this) {
14001                    dumpOomLocked(fd, pw, args, opti, true);
14002                }
14003            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14004                synchronized (this) {
14005                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14006                }
14007            } else if ("provider".equals(cmd)) {
14008                String[] newArgs;
14009                String name;
14010                if (opti >= args.length) {
14011                    name = null;
14012                    newArgs = EMPTY_STRING_ARRAY;
14013                } else {
14014                    name = args[opti];
14015                    opti++;
14016                    newArgs = new String[args.length - opti];
14017                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14018                }
14019                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14020                    pw.println("No providers match: " + name);
14021                    pw.println("Use -h for help.");
14022                }
14023            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14024                synchronized (this) {
14025                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14026                }
14027            } else if ("service".equals(cmd)) {
14028                String[] newArgs;
14029                String name;
14030                if (opti >= args.length) {
14031                    name = null;
14032                    newArgs = EMPTY_STRING_ARRAY;
14033                } else {
14034                    name = args[opti];
14035                    opti++;
14036                    newArgs = new String[args.length - opti];
14037                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14038                            args.length - opti);
14039                }
14040                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14041                    pw.println("No services match: " + name);
14042                    pw.println("Use -h for help.");
14043                }
14044            } else if ("package".equals(cmd)) {
14045                String[] newArgs;
14046                if (opti >= args.length) {
14047                    pw.println("package: no package name specified");
14048                    pw.println("Use -h for help.");
14049                } else {
14050                    dumpPackage = args[opti];
14051                    opti++;
14052                    newArgs = new String[args.length - opti];
14053                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14054                            args.length - opti);
14055                    args = newArgs;
14056                    opti = 0;
14057                    more = true;
14058                }
14059            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14060                synchronized (this) {
14061                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14062                }
14063            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14064                if (dumpClient) {
14065                    ActiveServices.ServiceDumper dumper;
14066                    synchronized (this) {
14067                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14068                                dumpPackage);
14069                    }
14070                    dumper.dumpWithClient();
14071                } else {
14072                    synchronized (this) {
14073                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14074                                dumpPackage).dumpLocked();
14075                    }
14076                }
14077            } else if ("locks".equals(cmd)) {
14078                LockGuard.dump(fd, pw, args);
14079            } else {
14080                // Dumping a single activity?
14081                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14082                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14083                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14084                    if (res < 0) {
14085                        pw.println("Bad activity command, or no activities match: " + cmd);
14086                        pw.println("Use -h for help.");
14087                    }
14088                }
14089            }
14090            if (!more) {
14091                Binder.restoreCallingIdentity(origId);
14092                return;
14093            }
14094        }
14095
14096        // No piece of data specified, dump everything.
14097        if (dumpCheckinFormat) {
14098            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14099        } else if (dumpClient) {
14100            ActiveServices.ServiceDumper sdumper;
14101            synchronized (this) {
14102                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14103                pw.println();
14104                if (dumpAll) {
14105                    pw.println("-------------------------------------------------------------------------------");
14106                }
14107                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14108                pw.println();
14109                if (dumpAll) {
14110                    pw.println("-------------------------------------------------------------------------------");
14111                }
14112                if (dumpAll || dumpPackage != null) {
14113                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14114                    pw.println();
14115                    if (dumpAll) {
14116                        pw.println("-------------------------------------------------------------------------------");
14117                    }
14118                }
14119                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14120                pw.println();
14121                if (dumpAll) {
14122                    pw.println("-------------------------------------------------------------------------------");
14123                }
14124                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14125                pw.println();
14126                if (dumpAll) {
14127                    pw.println("-------------------------------------------------------------------------------");
14128                }
14129                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14130                        dumpPackage);
14131            }
14132            sdumper.dumpWithClient();
14133            pw.println();
14134            synchronized (this) {
14135                if (dumpAll) {
14136                    pw.println("-------------------------------------------------------------------------------");
14137                }
14138                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14139                pw.println();
14140                if (dumpAll) {
14141                    pw.println("-------------------------------------------------------------------------------");
14142                }
14143                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14144                if (mAssociations.size() > 0) {
14145                    pw.println();
14146                    if (dumpAll) {
14147                        pw.println("-------------------------------------------------------------------------------");
14148                    }
14149                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14150                }
14151                pw.println();
14152                if (dumpAll) {
14153                    pw.println("-------------------------------------------------------------------------------");
14154                }
14155                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14156            }
14157
14158        } else {
14159            synchronized (this) {
14160                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14161                pw.println();
14162                if (dumpAll) {
14163                    pw.println("-------------------------------------------------------------------------------");
14164                }
14165                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14166                pw.println();
14167                if (dumpAll) {
14168                    pw.println("-------------------------------------------------------------------------------");
14169                }
14170                if (dumpAll || dumpPackage != null) {
14171                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14172                    pw.println();
14173                    if (dumpAll) {
14174                        pw.println("-------------------------------------------------------------------------------");
14175                    }
14176                }
14177                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14178                pw.println();
14179                if (dumpAll) {
14180                    pw.println("-------------------------------------------------------------------------------");
14181                }
14182                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14183                pw.println();
14184                if (dumpAll) {
14185                    pw.println("-------------------------------------------------------------------------------");
14186                }
14187                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14188                        .dumpLocked();
14189                pw.println();
14190                if (dumpAll) {
14191                    pw.println("-------------------------------------------------------------------------------");
14192                }
14193                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14194                pw.println();
14195                if (dumpAll) {
14196                    pw.println("-------------------------------------------------------------------------------");
14197                }
14198                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14199                if (mAssociations.size() > 0) {
14200                    pw.println();
14201                    if (dumpAll) {
14202                        pw.println("-------------------------------------------------------------------------------");
14203                    }
14204                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14205                }
14206                pw.println();
14207                if (dumpAll) {
14208                    pw.println("-------------------------------------------------------------------------------");
14209                }
14210                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14211            }
14212        }
14213        Binder.restoreCallingIdentity(origId);
14214    }
14215
14216    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14217            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14218        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14219
14220        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14221                dumpPackage);
14222        boolean needSep = printedAnything;
14223
14224        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14225                dumpPackage, needSep, "  mFocusedActivity: ");
14226        if (printed) {
14227            printedAnything = true;
14228            needSep = false;
14229        }
14230
14231        if (dumpPackage == null) {
14232            if (needSep) {
14233                pw.println();
14234            }
14235            needSep = true;
14236            printedAnything = true;
14237            mStackSupervisor.dump(pw, "  ");
14238        }
14239
14240        if (!printedAnything) {
14241            pw.println("  (nothing)");
14242        }
14243    }
14244
14245    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14246            int opti, boolean dumpAll, String dumpPackage) {
14247        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14248
14249        boolean printedAnything = false;
14250
14251        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14252            boolean printedHeader = false;
14253
14254            final int N = mRecentTasks.size();
14255            for (int i=0; i<N; i++) {
14256                TaskRecord tr = mRecentTasks.get(i);
14257                if (dumpPackage != null) {
14258                    if (tr.realActivity == null ||
14259                            !dumpPackage.equals(tr.realActivity)) {
14260                        continue;
14261                    }
14262                }
14263                if (!printedHeader) {
14264                    pw.println("  Recent tasks:");
14265                    printedHeader = true;
14266                    printedAnything = true;
14267                }
14268                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14269                        pw.println(tr);
14270                if (dumpAll) {
14271                    mRecentTasks.get(i).dump(pw, "    ");
14272                }
14273            }
14274        }
14275
14276        if (!printedAnything) {
14277            pw.println("  (nothing)");
14278        }
14279    }
14280
14281    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14282            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14283        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14284
14285        int dumpUid = 0;
14286        if (dumpPackage != null) {
14287            IPackageManager pm = AppGlobals.getPackageManager();
14288            try {
14289                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14290            } catch (RemoteException e) {
14291            }
14292        }
14293
14294        boolean printedAnything = false;
14295
14296        final long now = SystemClock.uptimeMillis();
14297
14298        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14299            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14300                    = mAssociations.valueAt(i1);
14301            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14302                SparseArray<ArrayMap<String, Association>> sourceUids
14303                        = targetComponents.valueAt(i2);
14304                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14305                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14306                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14307                        Association ass = sourceProcesses.valueAt(i4);
14308                        if (dumpPackage != null) {
14309                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14310                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14311                                continue;
14312                            }
14313                        }
14314                        printedAnything = true;
14315                        pw.print("  ");
14316                        pw.print(ass.mTargetProcess);
14317                        pw.print("/");
14318                        UserHandle.formatUid(pw, ass.mTargetUid);
14319                        pw.print(" <- ");
14320                        pw.print(ass.mSourceProcess);
14321                        pw.print("/");
14322                        UserHandle.formatUid(pw, ass.mSourceUid);
14323                        pw.println();
14324                        pw.print("    via ");
14325                        pw.print(ass.mTargetComponent.flattenToShortString());
14326                        pw.println();
14327                        pw.print("    ");
14328                        long dur = ass.mTime;
14329                        if (ass.mNesting > 0) {
14330                            dur += now - ass.mStartTime;
14331                        }
14332                        TimeUtils.formatDuration(dur, pw);
14333                        pw.print(" (");
14334                        pw.print(ass.mCount);
14335                        pw.print(" times)");
14336                        pw.print("  ");
14337                        for (int i=0; i<ass.mStateTimes.length; i++) {
14338                            long amt = ass.mStateTimes[i];
14339                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14340                                amt += now - ass.mLastStateUptime;
14341                            }
14342                            if (amt != 0) {
14343                                pw.print(" ");
14344                                pw.print(ProcessList.makeProcStateString(
14345                                            i + ActivityManager.MIN_PROCESS_STATE));
14346                                pw.print("=");
14347                                TimeUtils.formatDuration(amt, pw);
14348                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14349                                    pw.print("*");
14350                                }
14351                            }
14352                        }
14353                        pw.println();
14354                        if (ass.mNesting > 0) {
14355                            pw.print("    Currently active: ");
14356                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14357                            pw.println();
14358                        }
14359                    }
14360                }
14361            }
14362
14363        }
14364
14365        if (!printedAnything) {
14366            pw.println("  (nothing)");
14367        }
14368    }
14369
14370    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14371            String header, boolean needSep) {
14372        boolean printed = false;
14373        int whichAppId = -1;
14374        if (dumpPackage != null) {
14375            try {
14376                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14377                        dumpPackage, 0);
14378                whichAppId = UserHandle.getAppId(info.uid);
14379            } catch (NameNotFoundException e) {
14380                e.printStackTrace();
14381            }
14382        }
14383        for (int i=0; i<uids.size(); i++) {
14384            UidRecord uidRec = uids.valueAt(i);
14385            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14386                continue;
14387            }
14388            if (!printed) {
14389                printed = true;
14390                if (needSep) {
14391                    pw.println();
14392                }
14393                pw.print("  ");
14394                pw.println(header);
14395                needSep = true;
14396            }
14397            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14398            pw.print(": "); pw.println(uidRec);
14399        }
14400        return printed;
14401    }
14402
14403    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14404            int opti, boolean dumpAll, String dumpPackage) {
14405        boolean needSep = false;
14406        boolean printedAnything = false;
14407        int numPers = 0;
14408
14409        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14410
14411        if (dumpAll) {
14412            final int NP = mProcessNames.getMap().size();
14413            for (int ip=0; ip<NP; ip++) {
14414                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14415                final int NA = procs.size();
14416                for (int ia=0; ia<NA; ia++) {
14417                    ProcessRecord r = procs.valueAt(ia);
14418                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14419                        continue;
14420                    }
14421                    if (!needSep) {
14422                        pw.println("  All known processes:");
14423                        needSep = true;
14424                        printedAnything = true;
14425                    }
14426                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14427                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14428                        pw.print(" "); pw.println(r);
14429                    r.dump(pw, "    ");
14430                    if (r.persistent) {
14431                        numPers++;
14432                    }
14433                }
14434            }
14435        }
14436
14437        if (mIsolatedProcesses.size() > 0) {
14438            boolean printed = false;
14439            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14440                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14441                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14442                    continue;
14443                }
14444                if (!printed) {
14445                    if (needSep) {
14446                        pw.println();
14447                    }
14448                    pw.println("  Isolated process list (sorted by uid):");
14449                    printedAnything = true;
14450                    printed = true;
14451                    needSep = true;
14452                }
14453                pw.println(String.format("%sIsolated #%2d: %s",
14454                        "    ", i, r.toString()));
14455            }
14456        }
14457
14458        if (mActiveUids.size() > 0) {
14459            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14460                printedAnything = needSep = true;
14461            }
14462        }
14463        if (mValidateUids.size() > 0) {
14464            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14465                printedAnything = needSep = true;
14466            }
14467        }
14468
14469        if (mLruProcesses.size() > 0) {
14470            if (needSep) {
14471                pw.println();
14472            }
14473            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14474                    pw.print(" total, non-act at ");
14475                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14476                    pw.print(", non-svc at ");
14477                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14478                    pw.println("):");
14479            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14480            needSep = true;
14481            printedAnything = true;
14482        }
14483
14484        if (dumpAll || dumpPackage != null) {
14485            synchronized (mPidsSelfLocked) {
14486                boolean printed = false;
14487                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14488                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14489                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14490                        continue;
14491                    }
14492                    if (!printed) {
14493                        if (needSep) pw.println();
14494                        needSep = true;
14495                        pw.println("  PID mappings:");
14496                        printed = true;
14497                        printedAnything = true;
14498                    }
14499                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14500                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14501                }
14502            }
14503        }
14504
14505        if (mForegroundProcesses.size() > 0) {
14506            synchronized (mPidsSelfLocked) {
14507                boolean printed = false;
14508                for (int i=0; i<mForegroundProcesses.size(); i++) {
14509                    ProcessRecord r = mPidsSelfLocked.get(
14510                            mForegroundProcesses.valueAt(i).pid);
14511                    if (dumpPackage != null && (r == null
14512                            || !r.pkgList.containsKey(dumpPackage))) {
14513                        continue;
14514                    }
14515                    if (!printed) {
14516                        if (needSep) pw.println();
14517                        needSep = true;
14518                        pw.println("  Foreground Processes:");
14519                        printed = true;
14520                        printedAnything = true;
14521                    }
14522                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14523                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14524                }
14525            }
14526        }
14527
14528        if (mPersistentStartingProcesses.size() > 0) {
14529            if (needSep) pw.println();
14530            needSep = true;
14531            printedAnything = true;
14532            pw.println("  Persisent processes that are starting:");
14533            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14534                    "Starting Norm", "Restarting PERS", dumpPackage);
14535        }
14536
14537        if (mRemovedProcesses.size() > 0) {
14538            if (needSep) pw.println();
14539            needSep = true;
14540            printedAnything = true;
14541            pw.println("  Processes that are being removed:");
14542            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14543                    "Removed Norm", "Removed PERS", dumpPackage);
14544        }
14545
14546        if (mProcessesOnHold.size() > 0) {
14547            if (needSep) pw.println();
14548            needSep = true;
14549            printedAnything = true;
14550            pw.println("  Processes that are on old until the system is ready:");
14551            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14552                    "OnHold Norm", "OnHold PERS", dumpPackage);
14553        }
14554
14555        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14556
14557        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14558        if (needSep) {
14559            printedAnything = true;
14560        }
14561
14562        if (dumpPackage == null) {
14563            pw.println();
14564            needSep = false;
14565            mUserController.dump(pw, dumpAll);
14566        }
14567        if (mHomeProcess != null && (dumpPackage == null
14568                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14569            if (needSep) {
14570                pw.println();
14571                needSep = false;
14572            }
14573            pw.println("  mHomeProcess: " + mHomeProcess);
14574        }
14575        if (mPreviousProcess != null && (dumpPackage == null
14576                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14577            if (needSep) {
14578                pw.println();
14579                needSep = false;
14580            }
14581            pw.println("  mPreviousProcess: " + mPreviousProcess);
14582        }
14583        if (dumpAll) {
14584            StringBuilder sb = new StringBuilder(128);
14585            sb.append("  mPreviousProcessVisibleTime: ");
14586            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14587            pw.println(sb);
14588        }
14589        if (mHeavyWeightProcess != null && (dumpPackage == null
14590                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14591            if (needSep) {
14592                pw.println();
14593                needSep = false;
14594            }
14595            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14596        }
14597        if (dumpPackage == null) {
14598            pw.println("  mConfiguration: " + mConfiguration);
14599        }
14600        if (dumpAll) {
14601            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14602            if (mCompatModePackages.getPackages().size() > 0) {
14603                boolean printed = false;
14604                for (Map.Entry<String, Integer> entry
14605                        : mCompatModePackages.getPackages().entrySet()) {
14606                    String pkg = entry.getKey();
14607                    int mode = entry.getValue();
14608                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14609                        continue;
14610                    }
14611                    if (!printed) {
14612                        pw.println("  mScreenCompatPackages:");
14613                        printed = true;
14614                    }
14615                    pw.print("    "); pw.print(pkg); pw.print(": ");
14616                            pw.print(mode); pw.println();
14617                }
14618            }
14619        }
14620        if (dumpPackage == null) {
14621            pw.println("  mWakefulness="
14622                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14623            pw.println("  mSleepTokens=" + mSleepTokens);
14624            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14625                    + lockScreenShownToString());
14626            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14627            if (mRunningVoice != null) {
14628                pw.println("  mRunningVoice=" + mRunningVoice);
14629                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14630            }
14631        }
14632        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14633                || mOrigWaitForDebugger) {
14634            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14635                    || dumpPackage.equals(mOrigDebugApp)) {
14636                if (needSep) {
14637                    pw.println();
14638                    needSep = false;
14639                }
14640                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14641                        + " mDebugTransient=" + mDebugTransient
14642                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14643            }
14644        }
14645        if (mCurAppTimeTracker != null) {
14646            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14647        }
14648        if (mMemWatchProcesses.getMap().size() > 0) {
14649            pw.println("  Mem watch processes:");
14650            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14651                    = mMemWatchProcesses.getMap();
14652            for (int i=0; i<procs.size(); i++) {
14653                final String proc = procs.keyAt(i);
14654                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14655                for (int j=0; j<uids.size(); j++) {
14656                    if (needSep) {
14657                        pw.println();
14658                        needSep = false;
14659                    }
14660                    StringBuilder sb = new StringBuilder();
14661                    sb.append("    ").append(proc).append('/');
14662                    UserHandle.formatUid(sb, uids.keyAt(j));
14663                    Pair<Long, String> val = uids.valueAt(j);
14664                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14665                    if (val.second != null) {
14666                        sb.append(", report to ").append(val.second);
14667                    }
14668                    pw.println(sb.toString());
14669                }
14670            }
14671            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14672            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14673            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14674                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14675        }
14676        if (mTrackAllocationApp != null) {
14677            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14678                if (needSep) {
14679                    pw.println();
14680                    needSep = false;
14681                }
14682                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14683            }
14684        }
14685        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14686                || mProfileFd != null) {
14687            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14688                if (needSep) {
14689                    pw.println();
14690                    needSep = false;
14691                }
14692                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14693                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14694                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14695                        + mAutoStopProfiler);
14696                pw.println("  mProfileType=" + mProfileType);
14697            }
14698        }
14699        if (mNativeDebuggingApp != null) {
14700            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14701                if (needSep) {
14702                    pw.println();
14703                    needSep = false;
14704                }
14705                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14706            }
14707        }
14708        if (dumpPackage == null) {
14709            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14710                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14711                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14712            }
14713            if (mController != null) {
14714                pw.println("  mController=" + mController
14715                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14716            }
14717            if (dumpAll) {
14718                pw.println("  Total persistent processes: " + numPers);
14719                pw.println("  mProcessesReady=" + mProcessesReady
14720                        + " mSystemReady=" + mSystemReady
14721                        + " mBooted=" + mBooted
14722                        + " mFactoryTest=" + mFactoryTest);
14723                pw.println("  mBooting=" + mBooting
14724                        + " mCallFinishBooting=" + mCallFinishBooting
14725                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14726                pw.print("  mLastPowerCheckRealtime=");
14727                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14728                        pw.println("");
14729                pw.print("  mLastPowerCheckUptime=");
14730                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14731                        pw.println("");
14732                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14733                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14734                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14735                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14736                        + " (" + mLruProcesses.size() + " total)"
14737                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14738                        + " mNumServiceProcs=" + mNumServiceProcs
14739                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14740                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14741                        + " mLastMemoryLevel=" + mLastMemoryLevel
14742                        + " mLastNumProcesses=" + mLastNumProcesses);
14743                long now = SystemClock.uptimeMillis();
14744                pw.print("  mLastIdleTime=");
14745                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14746                        pw.print(" mLowRamSinceLastIdle=");
14747                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14748                        pw.println();
14749            }
14750        }
14751
14752        if (!printedAnything) {
14753            pw.println("  (nothing)");
14754        }
14755    }
14756
14757    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14758            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14759        if (mProcessesToGc.size() > 0) {
14760            boolean printed = false;
14761            long now = SystemClock.uptimeMillis();
14762            for (int i=0; i<mProcessesToGc.size(); i++) {
14763                ProcessRecord proc = mProcessesToGc.get(i);
14764                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14765                    continue;
14766                }
14767                if (!printed) {
14768                    if (needSep) pw.println();
14769                    needSep = true;
14770                    pw.println("  Processes that are waiting to GC:");
14771                    printed = true;
14772                }
14773                pw.print("    Process "); pw.println(proc);
14774                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14775                        pw.print(", last gced=");
14776                        pw.print(now-proc.lastRequestedGc);
14777                        pw.print(" ms ago, last lowMem=");
14778                        pw.print(now-proc.lastLowMemory);
14779                        pw.println(" ms ago");
14780
14781            }
14782        }
14783        return needSep;
14784    }
14785
14786    void printOomLevel(PrintWriter pw, String name, int adj) {
14787        pw.print("    ");
14788        if (adj >= 0) {
14789            pw.print(' ');
14790            if (adj < 10) pw.print(' ');
14791        } else {
14792            if (adj > -10) pw.print(' ');
14793        }
14794        pw.print(adj);
14795        pw.print(": ");
14796        pw.print(name);
14797        pw.print(" (");
14798        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14799        pw.println(")");
14800    }
14801
14802    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14803            int opti, boolean dumpAll) {
14804        boolean needSep = false;
14805
14806        if (mLruProcesses.size() > 0) {
14807            if (needSep) pw.println();
14808            needSep = true;
14809            pw.println("  OOM levels:");
14810            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14811            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14812            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14813            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14814            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14815            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14816            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14817            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14818            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14819            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14820            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14821            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14822            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14823            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14824
14825            if (needSep) pw.println();
14826            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14827                    pw.print(" total, non-act at ");
14828                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14829                    pw.print(", non-svc at ");
14830                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14831                    pw.println("):");
14832            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14833            needSep = true;
14834        }
14835
14836        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14837
14838        pw.println();
14839        pw.println("  mHomeProcess: " + mHomeProcess);
14840        pw.println("  mPreviousProcess: " + mPreviousProcess);
14841        if (mHeavyWeightProcess != null) {
14842            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14843        }
14844
14845        return true;
14846    }
14847
14848    /**
14849     * There are three ways to call this:
14850     *  - no provider specified: dump all the providers
14851     *  - a flattened component name that matched an existing provider was specified as the
14852     *    first arg: dump that one provider
14853     *  - the first arg isn't the flattened component name of an existing provider:
14854     *    dump all providers whose component contains the first arg as a substring
14855     */
14856    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14857            int opti, boolean dumpAll) {
14858        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14859    }
14860
14861    static class ItemMatcher {
14862        ArrayList<ComponentName> components;
14863        ArrayList<String> strings;
14864        ArrayList<Integer> objects;
14865        boolean all;
14866
14867        ItemMatcher() {
14868            all = true;
14869        }
14870
14871        void build(String name) {
14872            ComponentName componentName = ComponentName.unflattenFromString(name);
14873            if (componentName != null) {
14874                if (components == null) {
14875                    components = new ArrayList<ComponentName>();
14876                }
14877                components.add(componentName);
14878                all = false;
14879            } else {
14880                int objectId = 0;
14881                // Not a '/' separated full component name; maybe an object ID?
14882                try {
14883                    objectId = Integer.parseInt(name, 16);
14884                    if (objects == null) {
14885                        objects = new ArrayList<Integer>();
14886                    }
14887                    objects.add(objectId);
14888                    all = false;
14889                } catch (RuntimeException e) {
14890                    // Not an integer; just do string match.
14891                    if (strings == null) {
14892                        strings = new ArrayList<String>();
14893                    }
14894                    strings.add(name);
14895                    all = false;
14896                }
14897            }
14898        }
14899
14900        int build(String[] args, int opti) {
14901            for (; opti<args.length; opti++) {
14902                String name = args[opti];
14903                if ("--".equals(name)) {
14904                    return opti+1;
14905                }
14906                build(name);
14907            }
14908            return opti;
14909        }
14910
14911        boolean match(Object object, ComponentName comp) {
14912            if (all) {
14913                return true;
14914            }
14915            if (components != null) {
14916                for (int i=0; i<components.size(); i++) {
14917                    if (components.get(i).equals(comp)) {
14918                        return true;
14919                    }
14920                }
14921            }
14922            if (objects != null) {
14923                for (int i=0; i<objects.size(); i++) {
14924                    if (System.identityHashCode(object) == objects.get(i)) {
14925                        return true;
14926                    }
14927                }
14928            }
14929            if (strings != null) {
14930                String flat = comp.flattenToString();
14931                for (int i=0; i<strings.size(); i++) {
14932                    if (flat.contains(strings.get(i))) {
14933                        return true;
14934                    }
14935                }
14936            }
14937            return false;
14938        }
14939    }
14940
14941    /**
14942     * There are three things that cmd can be:
14943     *  - a flattened component name that matches an existing activity
14944     *  - the cmd arg isn't the flattened component name of an existing activity:
14945     *    dump all activity whose component contains the cmd as a substring
14946     *  - A hex number of the ActivityRecord object instance.
14947     */
14948    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14949            int opti, boolean dumpAll) {
14950        ArrayList<ActivityRecord> activities;
14951
14952        synchronized (this) {
14953            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14954        }
14955
14956        if (activities.size() <= 0) {
14957            return false;
14958        }
14959
14960        String[] newArgs = new String[args.length - opti];
14961        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14962
14963        TaskRecord lastTask = null;
14964        boolean needSep = false;
14965        for (int i=activities.size()-1; i>=0; i--) {
14966            ActivityRecord r = activities.get(i);
14967            if (needSep) {
14968                pw.println();
14969            }
14970            needSep = true;
14971            synchronized (this) {
14972                if (lastTask != r.task) {
14973                    lastTask = r.task;
14974                    pw.print("TASK "); pw.print(lastTask.affinity);
14975                            pw.print(" id="); pw.println(lastTask.taskId);
14976                    if (dumpAll) {
14977                        lastTask.dump(pw, "  ");
14978                    }
14979                }
14980            }
14981            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14982        }
14983        return true;
14984    }
14985
14986    /**
14987     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14988     * there is a thread associated with the activity.
14989     */
14990    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14991            final ActivityRecord r, String[] args, boolean dumpAll) {
14992        String innerPrefix = prefix + "  ";
14993        synchronized (this) {
14994            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14995                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14996                    pw.print(" pid=");
14997                    if (r.app != null) pw.println(r.app.pid);
14998                    else pw.println("(not running)");
14999            if (dumpAll) {
15000                r.dump(pw, innerPrefix);
15001            }
15002        }
15003        if (r.app != null && r.app.thread != null) {
15004            // flush anything that is already in the PrintWriter since the thread is going
15005            // to write to the file descriptor directly
15006            pw.flush();
15007            try {
15008                TransferPipe tp = new TransferPipe();
15009                try {
15010                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15011                            r.appToken, innerPrefix, args);
15012                    tp.go(fd);
15013                } finally {
15014                    tp.kill();
15015                }
15016            } catch (IOException e) {
15017                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15018            } catch (RemoteException e) {
15019                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15020            }
15021        }
15022    }
15023
15024    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15025            int opti, boolean dumpAll, String dumpPackage) {
15026        boolean needSep = false;
15027        boolean onlyHistory = false;
15028        boolean printedAnything = false;
15029
15030        if ("history".equals(dumpPackage)) {
15031            if (opti < args.length && "-s".equals(args[opti])) {
15032                dumpAll = false;
15033            }
15034            onlyHistory = true;
15035            dumpPackage = null;
15036        }
15037
15038        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15039        if (!onlyHistory && dumpAll) {
15040            if (mRegisteredReceivers.size() > 0) {
15041                boolean printed = false;
15042                Iterator it = mRegisteredReceivers.values().iterator();
15043                while (it.hasNext()) {
15044                    ReceiverList r = (ReceiverList)it.next();
15045                    if (dumpPackage != null && (r.app == null ||
15046                            !dumpPackage.equals(r.app.info.packageName))) {
15047                        continue;
15048                    }
15049                    if (!printed) {
15050                        pw.println("  Registered Receivers:");
15051                        needSep = true;
15052                        printed = true;
15053                        printedAnything = true;
15054                    }
15055                    pw.print("  * "); pw.println(r);
15056                    r.dump(pw, "    ");
15057                }
15058            }
15059
15060            if (mReceiverResolver.dump(pw, needSep ?
15061                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15062                    "    ", dumpPackage, false, false)) {
15063                needSep = true;
15064                printedAnything = true;
15065            }
15066        }
15067
15068        for (BroadcastQueue q : mBroadcastQueues) {
15069            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15070            printedAnything |= needSep;
15071        }
15072
15073        needSep = true;
15074
15075        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15076            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15077                if (needSep) {
15078                    pw.println();
15079                }
15080                needSep = true;
15081                printedAnything = true;
15082                pw.print("  Sticky broadcasts for user ");
15083                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15084                StringBuilder sb = new StringBuilder(128);
15085                for (Map.Entry<String, ArrayList<Intent>> ent
15086                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15087                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15088                    if (dumpAll) {
15089                        pw.println(":");
15090                        ArrayList<Intent> intents = ent.getValue();
15091                        final int N = intents.size();
15092                        for (int i=0; i<N; i++) {
15093                            sb.setLength(0);
15094                            sb.append("    Intent: ");
15095                            intents.get(i).toShortString(sb, false, true, false, false);
15096                            pw.println(sb.toString());
15097                            Bundle bundle = intents.get(i).getExtras();
15098                            if (bundle != null) {
15099                                pw.print("      ");
15100                                pw.println(bundle.toString());
15101                            }
15102                        }
15103                    } else {
15104                        pw.println("");
15105                    }
15106                }
15107            }
15108        }
15109
15110        if (!onlyHistory && dumpAll) {
15111            pw.println();
15112            for (BroadcastQueue queue : mBroadcastQueues) {
15113                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15114                        + queue.mBroadcastsScheduled);
15115            }
15116            pw.println("  mHandler:");
15117            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15118            needSep = true;
15119            printedAnything = true;
15120        }
15121
15122        if (!printedAnything) {
15123            pw.println("  (nothing)");
15124        }
15125    }
15126
15127    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15128            int opti, boolean dumpAll, String dumpPackage) {
15129        if (mCurBroadcastStats == null) {
15130            return;
15131        }
15132
15133        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15134        final long now = SystemClock.elapsedRealtime();
15135        if (mLastBroadcastStats != null) {
15136            pw.print("  Last stats (from ");
15137            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15138            pw.print(" to ");
15139            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15140            pw.print(", ");
15141            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15142                    - mLastBroadcastStats.mStartUptime, pw);
15143            pw.println(" uptime):");
15144            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15145                pw.println("    (nothing)");
15146            }
15147            pw.println();
15148        }
15149        pw.print("  Current stats (from ");
15150        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15151        pw.print(" to now, ");
15152        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15153                - mCurBroadcastStats.mStartUptime, pw);
15154        pw.println(" uptime):");
15155        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15156            pw.println("    (nothing)");
15157        }
15158    }
15159
15160    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15161            int opti, boolean fullCheckin, String dumpPackage) {
15162        if (mCurBroadcastStats == null) {
15163            return;
15164        }
15165
15166        if (mLastBroadcastStats != null) {
15167            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15168            if (fullCheckin) {
15169                mLastBroadcastStats = null;
15170                return;
15171            }
15172        }
15173        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15174        if (fullCheckin) {
15175            mCurBroadcastStats = null;
15176        }
15177    }
15178
15179    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15180            int opti, boolean dumpAll, String dumpPackage) {
15181        boolean needSep;
15182        boolean printedAnything = false;
15183
15184        ItemMatcher matcher = new ItemMatcher();
15185        matcher.build(args, opti);
15186
15187        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15188
15189        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15190        printedAnything |= needSep;
15191
15192        if (mLaunchingProviders.size() > 0) {
15193            boolean printed = false;
15194            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15195                ContentProviderRecord r = mLaunchingProviders.get(i);
15196                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15197                    continue;
15198                }
15199                if (!printed) {
15200                    if (needSep) pw.println();
15201                    needSep = true;
15202                    pw.println("  Launching content providers:");
15203                    printed = true;
15204                    printedAnything = true;
15205                }
15206                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15207                        pw.println(r);
15208            }
15209        }
15210
15211        if (!printedAnything) {
15212            pw.println("  (nothing)");
15213        }
15214    }
15215
15216    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15217            int opti, boolean dumpAll, String dumpPackage) {
15218        boolean needSep = false;
15219        boolean printedAnything = false;
15220
15221        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15222
15223        if (mGrantedUriPermissions.size() > 0) {
15224            boolean printed = false;
15225            int dumpUid = -2;
15226            if (dumpPackage != null) {
15227                try {
15228                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15229                            MATCH_UNINSTALLED_PACKAGES, 0);
15230                } catch (NameNotFoundException e) {
15231                    dumpUid = -1;
15232                }
15233            }
15234            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15235                int uid = mGrantedUriPermissions.keyAt(i);
15236                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15237                    continue;
15238                }
15239                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15240                if (!printed) {
15241                    if (needSep) pw.println();
15242                    needSep = true;
15243                    pw.println("  Granted Uri Permissions:");
15244                    printed = true;
15245                    printedAnything = true;
15246                }
15247                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15248                for (UriPermission perm : perms.values()) {
15249                    pw.print("    "); pw.println(perm);
15250                    if (dumpAll) {
15251                        perm.dump(pw, "      ");
15252                    }
15253                }
15254            }
15255        }
15256
15257        if (!printedAnything) {
15258            pw.println("  (nothing)");
15259        }
15260    }
15261
15262    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15263            int opti, boolean dumpAll, String dumpPackage) {
15264        boolean printed = false;
15265
15266        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15267
15268        if (mIntentSenderRecords.size() > 0) {
15269            Iterator<WeakReference<PendingIntentRecord>> it
15270                    = mIntentSenderRecords.values().iterator();
15271            while (it.hasNext()) {
15272                WeakReference<PendingIntentRecord> ref = it.next();
15273                PendingIntentRecord rec = ref != null ? ref.get(): null;
15274                if (dumpPackage != null && (rec == null
15275                        || !dumpPackage.equals(rec.key.packageName))) {
15276                    continue;
15277                }
15278                printed = true;
15279                if (rec != null) {
15280                    pw.print("  * "); pw.println(rec);
15281                    if (dumpAll) {
15282                        rec.dump(pw, "    ");
15283                    }
15284                } else {
15285                    pw.print("  * "); pw.println(ref);
15286                }
15287            }
15288        }
15289
15290        if (!printed) {
15291            pw.println("  (nothing)");
15292        }
15293    }
15294
15295    private static final int dumpProcessList(PrintWriter pw,
15296            ActivityManagerService service, List list,
15297            String prefix, String normalLabel, String persistentLabel,
15298            String dumpPackage) {
15299        int numPers = 0;
15300        final int N = list.size()-1;
15301        for (int i=N; i>=0; i--) {
15302            ProcessRecord r = (ProcessRecord)list.get(i);
15303            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15304                continue;
15305            }
15306            pw.println(String.format("%s%s #%2d: %s",
15307                    prefix, (r.persistent ? persistentLabel : normalLabel),
15308                    i, r.toString()));
15309            if (r.persistent) {
15310                numPers++;
15311            }
15312        }
15313        return numPers;
15314    }
15315
15316    private static final boolean dumpProcessOomList(PrintWriter pw,
15317            ActivityManagerService service, List<ProcessRecord> origList,
15318            String prefix, String normalLabel, String persistentLabel,
15319            boolean inclDetails, String dumpPackage) {
15320
15321        ArrayList<Pair<ProcessRecord, Integer>> list
15322                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15323        for (int i=0; i<origList.size(); i++) {
15324            ProcessRecord r = origList.get(i);
15325            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15326                continue;
15327            }
15328            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15329        }
15330
15331        if (list.size() <= 0) {
15332            return false;
15333        }
15334
15335        Comparator<Pair<ProcessRecord, Integer>> comparator
15336                = new Comparator<Pair<ProcessRecord, Integer>>() {
15337            @Override
15338            public int compare(Pair<ProcessRecord, Integer> object1,
15339                    Pair<ProcessRecord, Integer> object2) {
15340                if (object1.first.setAdj != object2.first.setAdj) {
15341                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15342                }
15343                if (object1.first.setProcState != object2.first.setProcState) {
15344                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15345                }
15346                if (object1.second.intValue() != object2.second.intValue()) {
15347                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15348                }
15349                return 0;
15350            }
15351        };
15352
15353        Collections.sort(list, comparator);
15354
15355        final long curRealtime = SystemClock.elapsedRealtime();
15356        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15357        final long curUptime = SystemClock.uptimeMillis();
15358        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15359
15360        for (int i=list.size()-1; i>=0; i--) {
15361            ProcessRecord r = list.get(i).first;
15362            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15363            char schedGroup;
15364            switch (r.setSchedGroup) {
15365                case ProcessList.SCHED_GROUP_BACKGROUND:
15366                    schedGroup = 'B';
15367                    break;
15368                case ProcessList.SCHED_GROUP_DEFAULT:
15369                    schedGroup = 'F';
15370                    break;
15371                case ProcessList.SCHED_GROUP_TOP_APP:
15372                    schedGroup = 'T';
15373                    break;
15374                default:
15375                    schedGroup = '?';
15376                    break;
15377            }
15378            char foreground;
15379            if (r.foregroundActivities) {
15380                foreground = 'A';
15381            } else if (r.foregroundServices) {
15382                foreground = 'S';
15383            } else {
15384                foreground = ' ';
15385            }
15386            String procState = ProcessList.makeProcStateString(r.curProcState);
15387            pw.print(prefix);
15388            pw.print(r.persistent ? persistentLabel : normalLabel);
15389            pw.print(" #");
15390            int num = (origList.size()-1)-list.get(i).second;
15391            if (num < 10) pw.print(' ');
15392            pw.print(num);
15393            pw.print(": ");
15394            pw.print(oomAdj);
15395            pw.print(' ');
15396            pw.print(schedGroup);
15397            pw.print('/');
15398            pw.print(foreground);
15399            pw.print('/');
15400            pw.print(procState);
15401            pw.print(" trm:");
15402            if (r.trimMemoryLevel < 10) pw.print(' ');
15403            pw.print(r.trimMemoryLevel);
15404            pw.print(' ');
15405            pw.print(r.toShortString());
15406            pw.print(" (");
15407            pw.print(r.adjType);
15408            pw.println(')');
15409            if (r.adjSource != null || r.adjTarget != null) {
15410                pw.print(prefix);
15411                pw.print("    ");
15412                if (r.adjTarget instanceof ComponentName) {
15413                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15414                } else if (r.adjTarget != null) {
15415                    pw.print(r.adjTarget.toString());
15416                } else {
15417                    pw.print("{null}");
15418                }
15419                pw.print("<=");
15420                if (r.adjSource instanceof ProcessRecord) {
15421                    pw.print("Proc{");
15422                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15423                    pw.println("}");
15424                } else if (r.adjSource != null) {
15425                    pw.println(r.adjSource.toString());
15426                } else {
15427                    pw.println("{null}");
15428                }
15429            }
15430            if (inclDetails) {
15431                pw.print(prefix);
15432                pw.print("    ");
15433                pw.print("oom: max="); pw.print(r.maxAdj);
15434                pw.print(" curRaw="); pw.print(r.curRawAdj);
15435                pw.print(" setRaw="); pw.print(r.setRawAdj);
15436                pw.print(" cur="); pw.print(r.curAdj);
15437                pw.print(" set="); pw.println(r.setAdj);
15438                pw.print(prefix);
15439                pw.print("    ");
15440                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15441                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15442                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15443                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15444                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15445                pw.println();
15446                pw.print(prefix);
15447                pw.print("    ");
15448                pw.print("cached="); pw.print(r.cached);
15449                pw.print(" empty="); pw.print(r.empty);
15450                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15451
15452                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15453                    if (r.lastWakeTime != 0) {
15454                        long wtime;
15455                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15456                        synchronized (stats) {
15457                            wtime = stats.getProcessWakeTime(r.info.uid,
15458                                    r.pid, curRealtime);
15459                        }
15460                        long timeUsed = wtime - r.lastWakeTime;
15461                        pw.print(prefix);
15462                        pw.print("    ");
15463                        pw.print("keep awake over ");
15464                        TimeUtils.formatDuration(realtimeSince, pw);
15465                        pw.print(" used ");
15466                        TimeUtils.formatDuration(timeUsed, pw);
15467                        pw.print(" (");
15468                        pw.print((timeUsed*100)/realtimeSince);
15469                        pw.println("%)");
15470                    }
15471                    if (r.lastCpuTime != 0) {
15472                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15473                        pw.print(prefix);
15474                        pw.print("    ");
15475                        pw.print("run cpu over ");
15476                        TimeUtils.formatDuration(uptimeSince, pw);
15477                        pw.print(" used ");
15478                        TimeUtils.formatDuration(timeUsed, pw);
15479                        pw.print(" (");
15480                        pw.print((timeUsed*100)/uptimeSince);
15481                        pw.println("%)");
15482                    }
15483                }
15484            }
15485        }
15486        return true;
15487    }
15488
15489    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15490            String[] args) {
15491        ArrayList<ProcessRecord> procs;
15492        synchronized (this) {
15493            if (args != null && args.length > start
15494                    && args[start].charAt(0) != '-') {
15495                procs = new ArrayList<ProcessRecord>();
15496                int pid = -1;
15497                try {
15498                    pid = Integer.parseInt(args[start]);
15499                } catch (NumberFormatException e) {
15500                }
15501                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15502                    ProcessRecord proc = mLruProcesses.get(i);
15503                    if (proc.pid == pid) {
15504                        procs.add(proc);
15505                    } else if (allPkgs && proc.pkgList != null
15506                            && proc.pkgList.containsKey(args[start])) {
15507                        procs.add(proc);
15508                    } else if (proc.processName.equals(args[start])) {
15509                        procs.add(proc);
15510                    }
15511                }
15512                if (procs.size() <= 0) {
15513                    return null;
15514                }
15515            } else {
15516                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15517            }
15518        }
15519        return procs;
15520    }
15521
15522    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15523            PrintWriter pw, String[] args) {
15524        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15525        if (procs == null) {
15526            pw.println("No process found for: " + args[0]);
15527            return;
15528        }
15529
15530        long uptime = SystemClock.uptimeMillis();
15531        long realtime = SystemClock.elapsedRealtime();
15532        pw.println("Applications Graphics Acceleration Info:");
15533        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15534
15535        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15536            ProcessRecord r = procs.get(i);
15537            if (r.thread != null) {
15538                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15539                pw.flush();
15540                try {
15541                    TransferPipe tp = new TransferPipe();
15542                    try {
15543                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15544                        tp.go(fd);
15545                    } finally {
15546                        tp.kill();
15547                    }
15548                } catch (IOException e) {
15549                    pw.println("Failure while dumping the app: " + r);
15550                    pw.flush();
15551                } catch (RemoteException e) {
15552                    pw.println("Got a RemoteException while dumping the app " + r);
15553                    pw.flush();
15554                }
15555            }
15556        }
15557    }
15558
15559    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15560        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15561        if (procs == null) {
15562            pw.println("No process found for: " + args[0]);
15563            return;
15564        }
15565
15566        pw.println("Applications Database Info:");
15567
15568        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15569            ProcessRecord r = procs.get(i);
15570            if (r.thread != null) {
15571                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15572                pw.flush();
15573                try {
15574                    TransferPipe tp = new TransferPipe();
15575                    try {
15576                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15577                        tp.go(fd);
15578                    } finally {
15579                        tp.kill();
15580                    }
15581                } catch (IOException e) {
15582                    pw.println("Failure while dumping the app: " + r);
15583                    pw.flush();
15584                } catch (RemoteException e) {
15585                    pw.println("Got a RemoteException while dumping the app " + r);
15586                    pw.flush();
15587                }
15588            }
15589        }
15590    }
15591
15592    final static class MemItem {
15593        final boolean isProc;
15594        final String label;
15595        final String shortLabel;
15596        final long pss;
15597        final long swapPss;
15598        final int id;
15599        final boolean hasActivities;
15600        ArrayList<MemItem> subitems;
15601
15602        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15603                boolean _hasActivities) {
15604            isProc = true;
15605            label = _label;
15606            shortLabel = _shortLabel;
15607            pss = _pss;
15608            swapPss = _swapPss;
15609            id = _id;
15610            hasActivities = _hasActivities;
15611        }
15612
15613        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15614            isProc = false;
15615            label = _label;
15616            shortLabel = _shortLabel;
15617            pss = _pss;
15618            swapPss = _swapPss;
15619            id = _id;
15620            hasActivities = false;
15621        }
15622    }
15623
15624    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15625            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15626        if (sort && !isCompact) {
15627            Collections.sort(items, new Comparator<MemItem>() {
15628                @Override
15629                public int compare(MemItem lhs, MemItem rhs) {
15630                    if (lhs.pss < rhs.pss) {
15631                        return 1;
15632                    } else if (lhs.pss > rhs.pss) {
15633                        return -1;
15634                    }
15635                    return 0;
15636                }
15637            });
15638        }
15639
15640        for (int i=0; i<items.size(); i++) {
15641            MemItem mi = items.get(i);
15642            if (!isCompact) {
15643                if (dumpSwapPss) {
15644                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15645                            mi.label, stringifyKBSize(mi.swapPss));
15646                } else {
15647                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15648                }
15649            } else if (mi.isProc) {
15650                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15651                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15652                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15653                pw.println(mi.hasActivities ? ",a" : ",e");
15654            } else {
15655                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15656                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15657            }
15658            if (mi.subitems != null) {
15659                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15660                        true, isCompact, dumpSwapPss);
15661            }
15662        }
15663    }
15664
15665    // These are in KB.
15666    static final long[] DUMP_MEM_BUCKETS = new long[] {
15667        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15668        120*1024, 160*1024, 200*1024,
15669        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15670        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15671    };
15672
15673    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15674            boolean stackLike) {
15675        int start = label.lastIndexOf('.');
15676        if (start >= 0) start++;
15677        else start = 0;
15678        int end = label.length();
15679        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15680            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15681                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15682                out.append(bucket);
15683                out.append(stackLike ? "MB." : "MB ");
15684                out.append(label, start, end);
15685                return;
15686            }
15687        }
15688        out.append(memKB/1024);
15689        out.append(stackLike ? "MB." : "MB ");
15690        out.append(label, start, end);
15691    }
15692
15693    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15694            ProcessList.NATIVE_ADJ,
15695            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15696            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15697            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15698            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15699            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15700            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15701    };
15702    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15703            "Native",
15704            "System", "Persistent", "Persistent Service", "Foreground",
15705            "Visible", "Perceptible",
15706            "Heavy Weight", "Backup",
15707            "A Services", "Home",
15708            "Previous", "B Services", "Cached"
15709    };
15710    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15711            "native",
15712            "sys", "pers", "persvc", "fore",
15713            "vis", "percept",
15714            "heavy", "backup",
15715            "servicea", "home",
15716            "prev", "serviceb", "cached"
15717    };
15718
15719    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15720            long realtime, boolean isCheckinRequest, boolean isCompact) {
15721        if (isCompact) {
15722            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15723        }
15724        if (isCheckinRequest || isCompact) {
15725            // short checkin version
15726            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15727        } else {
15728            pw.println("Applications Memory Usage (in Kilobytes):");
15729            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15730        }
15731    }
15732
15733    private static final int KSM_SHARED = 0;
15734    private static final int KSM_SHARING = 1;
15735    private static final int KSM_UNSHARED = 2;
15736    private static final int KSM_VOLATILE = 3;
15737
15738    private final long[] getKsmInfo() {
15739        long[] longOut = new long[4];
15740        final int[] SINGLE_LONG_FORMAT = new int[] {
15741            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15742        };
15743        long[] longTmp = new long[1];
15744        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15745                SINGLE_LONG_FORMAT, null, longTmp, null);
15746        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15747        longTmp[0] = 0;
15748        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15749                SINGLE_LONG_FORMAT, null, longTmp, null);
15750        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15751        longTmp[0] = 0;
15752        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15753                SINGLE_LONG_FORMAT, null, longTmp, null);
15754        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15755        longTmp[0] = 0;
15756        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15757                SINGLE_LONG_FORMAT, null, longTmp, null);
15758        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15759        return longOut;
15760    }
15761
15762    private static String stringifySize(long size, int order) {
15763        Locale locale = Locale.US;
15764        switch (order) {
15765            case 1:
15766                return String.format(locale, "%,13d", size);
15767            case 1024:
15768                return String.format(locale, "%,9dK", size / 1024);
15769            case 1024 * 1024:
15770                return String.format(locale, "%,5dM", size / 1024 / 1024);
15771            case 1024 * 1024 * 1024:
15772                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15773            default:
15774                throw new IllegalArgumentException("Invalid size order");
15775        }
15776    }
15777
15778    private static String stringifyKBSize(long size) {
15779        return stringifySize(size * 1024, 1024);
15780    }
15781
15782    // Update this version number in case you change the 'compact' format
15783    private static final int MEMINFO_COMPACT_VERSION = 1;
15784
15785    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15786            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15787        boolean dumpDetails = false;
15788        boolean dumpFullDetails = false;
15789        boolean dumpDalvik = false;
15790        boolean dumpSummaryOnly = false;
15791        boolean dumpUnreachable = false;
15792        boolean oomOnly = false;
15793        boolean isCompact = false;
15794        boolean localOnly = false;
15795        boolean packages = false;
15796        boolean isCheckinRequest = false;
15797        boolean dumpSwapPss = false;
15798
15799        int opti = 0;
15800        while (opti < args.length) {
15801            String opt = args[opti];
15802            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15803                break;
15804            }
15805            opti++;
15806            if ("-a".equals(opt)) {
15807                dumpDetails = true;
15808                dumpFullDetails = true;
15809                dumpDalvik = true;
15810                dumpSwapPss = true;
15811            } else if ("-d".equals(opt)) {
15812                dumpDalvik = true;
15813            } else if ("-c".equals(opt)) {
15814                isCompact = true;
15815            } else if ("-s".equals(opt)) {
15816                dumpDetails = true;
15817                dumpSummaryOnly = true;
15818            } else if ("-S".equals(opt)) {
15819                dumpSwapPss = true;
15820            } else if ("--unreachable".equals(opt)) {
15821                dumpUnreachable = true;
15822            } else if ("--oom".equals(opt)) {
15823                oomOnly = true;
15824            } else if ("--local".equals(opt)) {
15825                localOnly = true;
15826            } else if ("--package".equals(opt)) {
15827                packages = true;
15828            } else if ("--checkin".equals(opt)) {
15829                isCheckinRequest = true;
15830
15831            } else if ("-h".equals(opt)) {
15832                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15833                pw.println("  -a: include all available information for each process.");
15834                pw.println("  -d: include dalvik details.");
15835                pw.println("  -c: dump in a compact machine-parseable representation.");
15836                pw.println("  -s: dump only summary of application memory usage.");
15837                pw.println("  -S: dump also SwapPss.");
15838                pw.println("  --oom: only show processes organized by oom adj.");
15839                pw.println("  --local: only collect details locally, don't call process.");
15840                pw.println("  --package: interpret process arg as package, dumping all");
15841                pw.println("             processes that have loaded that package.");
15842                pw.println("  --checkin: dump data for a checkin");
15843                pw.println("If [process] is specified it can be the name or ");
15844                pw.println("pid of a specific process to dump.");
15845                return;
15846            } else {
15847                pw.println("Unknown argument: " + opt + "; use -h for help");
15848            }
15849        }
15850
15851        long uptime = SystemClock.uptimeMillis();
15852        long realtime = SystemClock.elapsedRealtime();
15853        final long[] tmpLong = new long[1];
15854
15855        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15856        if (procs == null) {
15857            // No Java processes.  Maybe they want to print a native process.
15858            if (args != null && args.length > opti
15859                    && args[opti].charAt(0) != '-') {
15860                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15861                        = new ArrayList<ProcessCpuTracker.Stats>();
15862                updateCpuStatsNow();
15863                int findPid = -1;
15864                try {
15865                    findPid = Integer.parseInt(args[opti]);
15866                } catch (NumberFormatException e) {
15867                }
15868                synchronized (mProcessCpuTracker) {
15869                    final int N = mProcessCpuTracker.countStats();
15870                    for (int i=0; i<N; i++) {
15871                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15872                        if (st.pid == findPid || (st.baseName != null
15873                                && st.baseName.equals(args[opti]))) {
15874                            nativeProcs.add(st);
15875                        }
15876                    }
15877                }
15878                if (nativeProcs.size() > 0) {
15879                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15880                            isCompact);
15881                    Debug.MemoryInfo mi = null;
15882                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15883                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15884                        final int pid = r.pid;
15885                        if (!isCheckinRequest && dumpDetails) {
15886                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15887                        }
15888                        if (mi == null) {
15889                            mi = new Debug.MemoryInfo();
15890                        }
15891                        if (dumpDetails || (!brief && !oomOnly)) {
15892                            Debug.getMemoryInfo(pid, mi);
15893                        } else {
15894                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15895                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15896                        }
15897                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15898                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15899                        if (isCheckinRequest) {
15900                            pw.println();
15901                        }
15902                    }
15903                    return;
15904                }
15905            }
15906            pw.println("No process found for: " + args[opti]);
15907            return;
15908        }
15909
15910        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15911            dumpDetails = true;
15912        }
15913
15914        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15915
15916        String[] innerArgs = new String[args.length-opti];
15917        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15918
15919        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15920        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15921        long nativePss = 0;
15922        long nativeSwapPss = 0;
15923        long dalvikPss = 0;
15924        long dalvikSwapPss = 0;
15925        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15926                EmptyArray.LONG;
15927        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15928                EmptyArray.LONG;
15929        long otherPss = 0;
15930        long otherSwapPss = 0;
15931        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15932        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15933
15934        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15935        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15936        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15937                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15938
15939        long totalPss = 0;
15940        long totalSwapPss = 0;
15941        long cachedPss = 0;
15942        long cachedSwapPss = 0;
15943        boolean hasSwapPss = false;
15944
15945        Debug.MemoryInfo mi = null;
15946        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15947            final ProcessRecord r = procs.get(i);
15948            final IApplicationThread thread;
15949            final int pid;
15950            final int oomAdj;
15951            final boolean hasActivities;
15952            synchronized (this) {
15953                thread = r.thread;
15954                pid = r.pid;
15955                oomAdj = r.getSetAdjWithServices();
15956                hasActivities = r.activities.size() > 0;
15957            }
15958            if (thread != null) {
15959                if (!isCheckinRequest && dumpDetails) {
15960                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15961                }
15962                if (mi == null) {
15963                    mi = new Debug.MemoryInfo();
15964                }
15965                if (dumpDetails || (!brief && !oomOnly)) {
15966                    Debug.getMemoryInfo(pid, mi);
15967                    hasSwapPss = mi.hasSwappedOutPss;
15968                } else {
15969                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15970                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15971                }
15972                if (dumpDetails) {
15973                    if (localOnly) {
15974                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15975                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15976                        if (isCheckinRequest) {
15977                            pw.println();
15978                        }
15979                    } else {
15980                        try {
15981                            pw.flush();
15982                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15983                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15984                        } catch (RemoteException e) {
15985                            if (!isCheckinRequest) {
15986                                pw.println("Got RemoteException!");
15987                                pw.flush();
15988                            }
15989                        }
15990                    }
15991                }
15992
15993                final long myTotalPss = mi.getTotalPss();
15994                final long myTotalUss = mi.getTotalUss();
15995                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15996
15997                synchronized (this) {
15998                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15999                        // Record this for posterity if the process has been stable.
16000                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16001                    }
16002                }
16003
16004                if (!isCheckinRequest && mi != null) {
16005                    totalPss += myTotalPss;
16006                    totalSwapPss += myTotalSwapPss;
16007                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16008                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16009                            myTotalSwapPss, pid, hasActivities);
16010                    procMems.add(pssItem);
16011                    procMemsMap.put(pid, pssItem);
16012
16013                    nativePss += mi.nativePss;
16014                    nativeSwapPss += mi.nativeSwappedOutPss;
16015                    dalvikPss += mi.dalvikPss;
16016                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16017                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16018                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16019                        dalvikSubitemSwapPss[j] +=
16020                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16021                    }
16022                    otherPss += mi.otherPss;
16023                    otherSwapPss += mi.otherSwappedOutPss;
16024                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16025                        long mem = mi.getOtherPss(j);
16026                        miscPss[j] += mem;
16027                        otherPss -= mem;
16028                        mem = mi.getOtherSwappedOutPss(j);
16029                        miscSwapPss[j] += mem;
16030                        otherSwapPss -= mem;
16031                    }
16032
16033                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16034                        cachedPss += myTotalPss;
16035                        cachedSwapPss += myTotalSwapPss;
16036                    }
16037
16038                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16039                        if (oomIndex == (oomPss.length - 1)
16040                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16041                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16042                            oomPss[oomIndex] += myTotalPss;
16043                            oomSwapPss[oomIndex] += myTotalSwapPss;
16044                            if (oomProcs[oomIndex] == null) {
16045                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16046                            }
16047                            oomProcs[oomIndex].add(pssItem);
16048                            break;
16049                        }
16050                    }
16051                }
16052            }
16053        }
16054
16055        long nativeProcTotalPss = 0;
16056
16057        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16058            // If we are showing aggregations, also look for native processes to
16059            // include so that our aggregations are more accurate.
16060            updateCpuStatsNow();
16061            mi = null;
16062            synchronized (mProcessCpuTracker) {
16063                final int N = mProcessCpuTracker.countStats();
16064                for (int i=0; i<N; i++) {
16065                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16066                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16067                        if (mi == null) {
16068                            mi = new Debug.MemoryInfo();
16069                        }
16070                        if (!brief && !oomOnly) {
16071                            Debug.getMemoryInfo(st.pid, mi);
16072                        } else {
16073                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16074                            mi.nativePrivateDirty = (int)tmpLong[0];
16075                        }
16076
16077                        final long myTotalPss = mi.getTotalPss();
16078                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16079                        totalPss += myTotalPss;
16080                        nativeProcTotalPss += myTotalPss;
16081
16082                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16083                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16084                        procMems.add(pssItem);
16085
16086                        nativePss += mi.nativePss;
16087                        nativeSwapPss += mi.nativeSwappedOutPss;
16088                        dalvikPss += mi.dalvikPss;
16089                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16090                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16091                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16092                            dalvikSubitemSwapPss[j] +=
16093                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16094                        }
16095                        otherPss += mi.otherPss;
16096                        otherSwapPss += mi.otherSwappedOutPss;
16097                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16098                            long mem = mi.getOtherPss(j);
16099                            miscPss[j] += mem;
16100                            otherPss -= mem;
16101                            mem = mi.getOtherSwappedOutPss(j);
16102                            miscSwapPss[j] += mem;
16103                            otherSwapPss -= mem;
16104                        }
16105                        oomPss[0] += myTotalPss;
16106                        oomSwapPss[0] += myTotalSwapPss;
16107                        if (oomProcs[0] == null) {
16108                            oomProcs[0] = new ArrayList<MemItem>();
16109                        }
16110                        oomProcs[0].add(pssItem);
16111                    }
16112                }
16113            }
16114
16115            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16116
16117            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16118            final MemItem dalvikItem =
16119                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16120            if (dalvikSubitemPss.length > 0) {
16121                dalvikItem.subitems = new ArrayList<MemItem>();
16122                for (int j=0; j<dalvikSubitemPss.length; j++) {
16123                    final String name = Debug.MemoryInfo.getOtherLabel(
16124                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16125                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16126                                    dalvikSubitemSwapPss[j], j));
16127                }
16128            }
16129            catMems.add(dalvikItem);
16130            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16131            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16132                String label = Debug.MemoryInfo.getOtherLabel(j);
16133                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16134            }
16135
16136            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16137            for (int j=0; j<oomPss.length; j++) {
16138                if (oomPss[j] != 0) {
16139                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16140                            : DUMP_MEM_OOM_LABEL[j];
16141                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16142                            DUMP_MEM_OOM_ADJ[j]);
16143                    item.subitems = oomProcs[j];
16144                    oomMems.add(item);
16145                }
16146            }
16147
16148            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16149            if (!brief && !oomOnly && !isCompact) {
16150                pw.println();
16151                pw.println("Total PSS by process:");
16152                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16153                pw.println();
16154            }
16155            if (!isCompact) {
16156                pw.println("Total PSS by OOM adjustment:");
16157            }
16158            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16159            if (!brief && !oomOnly) {
16160                PrintWriter out = categoryPw != null ? categoryPw : pw;
16161                if (!isCompact) {
16162                    out.println();
16163                    out.println("Total PSS by category:");
16164                }
16165                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16166            }
16167            if (!isCompact) {
16168                pw.println();
16169            }
16170            MemInfoReader memInfo = new MemInfoReader();
16171            memInfo.readMemInfo();
16172            if (nativeProcTotalPss > 0) {
16173                synchronized (this) {
16174                    final long cachedKb = memInfo.getCachedSizeKb();
16175                    final long freeKb = memInfo.getFreeSizeKb();
16176                    final long zramKb = memInfo.getZramTotalSizeKb();
16177                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16178                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16179                            kernelKb*1024, nativeProcTotalPss*1024);
16180                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16181                            nativeProcTotalPss);
16182                }
16183            }
16184            if (!brief) {
16185                if (!isCompact) {
16186                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16187                    pw.print(" (status ");
16188                    switch (mLastMemoryLevel) {
16189                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16190                            pw.println("normal)");
16191                            break;
16192                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16193                            pw.println("moderate)");
16194                            break;
16195                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16196                            pw.println("low)");
16197                            break;
16198                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16199                            pw.println("critical)");
16200                            break;
16201                        default:
16202                            pw.print(mLastMemoryLevel);
16203                            pw.println(")");
16204                            break;
16205                    }
16206                    pw.print(" Free RAM: ");
16207                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16208                            + memInfo.getFreeSizeKb()));
16209                    pw.print(" (");
16210                    pw.print(stringifyKBSize(cachedPss));
16211                    pw.print(" cached pss + ");
16212                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16213                    pw.print(" cached kernel + ");
16214                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16215                    pw.println(" free)");
16216                } else {
16217                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16218                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16219                            + memInfo.getFreeSizeKb()); pw.print(",");
16220                    pw.println(totalPss - cachedPss);
16221                }
16222            }
16223            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16224                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16225                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16226            if (!isCompact) {
16227                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16228                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16229                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16230                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16231                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16232            } else {
16233                pw.print("lostram,"); pw.println(lostRAM);
16234            }
16235            if (!brief) {
16236                if (memInfo.getZramTotalSizeKb() != 0) {
16237                    if (!isCompact) {
16238                        pw.print("     ZRAM: ");
16239                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16240                                pw.print(" physical used for ");
16241                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16242                                        - memInfo.getSwapFreeSizeKb()));
16243                                pw.print(" in swap (");
16244                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16245                                pw.println(" total swap)");
16246                    } else {
16247                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16248                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16249                                pw.println(memInfo.getSwapFreeSizeKb());
16250                    }
16251                }
16252                final long[] ksm = getKsmInfo();
16253                if (!isCompact) {
16254                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16255                            || ksm[KSM_VOLATILE] != 0) {
16256                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16257                                pw.print(" saved from shared ");
16258                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16259                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16260                                pw.print(" unshared; ");
16261                                pw.print(stringifyKBSize(
16262                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16263                    }
16264                    pw.print("   Tuning: ");
16265                    pw.print(ActivityManager.staticGetMemoryClass());
16266                    pw.print(" (large ");
16267                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16268                    pw.print("), oom ");
16269                    pw.print(stringifySize(
16270                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16271                    pw.print(", restore limit ");
16272                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16273                    if (ActivityManager.isLowRamDeviceStatic()) {
16274                        pw.print(" (low-ram)");
16275                    }
16276                    if (ActivityManager.isHighEndGfx()) {
16277                        pw.print(" (high-end-gfx)");
16278                    }
16279                    pw.println();
16280                } else {
16281                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16282                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16283                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16284                    pw.print("tuning,");
16285                    pw.print(ActivityManager.staticGetMemoryClass());
16286                    pw.print(',');
16287                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16288                    pw.print(',');
16289                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16290                    if (ActivityManager.isLowRamDeviceStatic()) {
16291                        pw.print(",low-ram");
16292                    }
16293                    if (ActivityManager.isHighEndGfx()) {
16294                        pw.print(",high-end-gfx");
16295                    }
16296                    pw.println();
16297                }
16298            }
16299        }
16300    }
16301
16302    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16303            long memtrack, String name) {
16304        sb.append("  ");
16305        sb.append(ProcessList.makeOomAdjString(oomAdj));
16306        sb.append(' ');
16307        sb.append(ProcessList.makeProcStateString(procState));
16308        sb.append(' ');
16309        ProcessList.appendRamKb(sb, pss);
16310        sb.append(": ");
16311        sb.append(name);
16312        if (memtrack > 0) {
16313            sb.append(" (");
16314            sb.append(stringifyKBSize(memtrack));
16315            sb.append(" memtrack)");
16316        }
16317    }
16318
16319    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16320        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16321        sb.append(" (pid ");
16322        sb.append(mi.pid);
16323        sb.append(") ");
16324        sb.append(mi.adjType);
16325        sb.append('\n');
16326        if (mi.adjReason != null) {
16327            sb.append("                      ");
16328            sb.append(mi.adjReason);
16329            sb.append('\n');
16330        }
16331    }
16332
16333    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16334        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16335        for (int i=0, N=memInfos.size(); i<N; i++) {
16336            ProcessMemInfo mi = memInfos.get(i);
16337            infoMap.put(mi.pid, mi);
16338        }
16339        updateCpuStatsNow();
16340        long[] memtrackTmp = new long[1];
16341        synchronized (mProcessCpuTracker) {
16342            final int N = mProcessCpuTracker.countStats();
16343            for (int i=0; i<N; i++) {
16344                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16345                if (st.vsize > 0) {
16346                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16347                    if (pss > 0) {
16348                        if (infoMap.indexOfKey(st.pid) < 0) {
16349                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16350                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16351                            mi.pss = pss;
16352                            mi.memtrack = memtrackTmp[0];
16353                            memInfos.add(mi);
16354                        }
16355                    }
16356                }
16357            }
16358        }
16359
16360        long totalPss = 0;
16361        long totalMemtrack = 0;
16362        for (int i=0, N=memInfos.size(); i<N; i++) {
16363            ProcessMemInfo mi = memInfos.get(i);
16364            if (mi.pss == 0) {
16365                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16366                mi.memtrack = memtrackTmp[0];
16367            }
16368            totalPss += mi.pss;
16369            totalMemtrack += mi.memtrack;
16370        }
16371        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16372            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16373                if (lhs.oomAdj != rhs.oomAdj) {
16374                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16375                }
16376                if (lhs.pss != rhs.pss) {
16377                    return lhs.pss < rhs.pss ? 1 : -1;
16378                }
16379                return 0;
16380            }
16381        });
16382
16383        StringBuilder tag = new StringBuilder(128);
16384        StringBuilder stack = new StringBuilder(128);
16385        tag.append("Low on memory -- ");
16386        appendMemBucket(tag, totalPss, "total", false);
16387        appendMemBucket(stack, totalPss, "total", true);
16388
16389        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16390        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16391        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16392
16393        boolean firstLine = true;
16394        int lastOomAdj = Integer.MIN_VALUE;
16395        long extraNativeRam = 0;
16396        long extraNativeMemtrack = 0;
16397        long cachedPss = 0;
16398        for (int i=0, N=memInfos.size(); i<N; i++) {
16399            ProcessMemInfo mi = memInfos.get(i);
16400
16401            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16402                cachedPss += mi.pss;
16403            }
16404
16405            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16406                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16407                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16408                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16409                if (lastOomAdj != mi.oomAdj) {
16410                    lastOomAdj = mi.oomAdj;
16411                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16412                        tag.append(" / ");
16413                    }
16414                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16415                        if (firstLine) {
16416                            stack.append(":");
16417                            firstLine = false;
16418                        }
16419                        stack.append("\n\t at ");
16420                    } else {
16421                        stack.append("$");
16422                    }
16423                } else {
16424                    tag.append(" ");
16425                    stack.append("$");
16426                }
16427                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16428                    appendMemBucket(tag, mi.pss, mi.name, false);
16429                }
16430                appendMemBucket(stack, mi.pss, mi.name, true);
16431                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16432                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16433                    stack.append("(");
16434                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16435                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16436                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16437                            stack.append(":");
16438                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16439                        }
16440                    }
16441                    stack.append(")");
16442                }
16443            }
16444
16445            appendMemInfo(fullNativeBuilder, mi);
16446            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16447                // The short form only has native processes that are >= 512K.
16448                if (mi.pss >= 512) {
16449                    appendMemInfo(shortNativeBuilder, mi);
16450                } else {
16451                    extraNativeRam += mi.pss;
16452                    extraNativeMemtrack += mi.memtrack;
16453                }
16454            } else {
16455                // Short form has all other details, but if we have collected RAM
16456                // from smaller native processes let's dump a summary of that.
16457                if (extraNativeRam > 0) {
16458                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16459                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16460                    shortNativeBuilder.append('\n');
16461                    extraNativeRam = 0;
16462                }
16463                appendMemInfo(fullJavaBuilder, mi);
16464            }
16465        }
16466
16467        fullJavaBuilder.append("           ");
16468        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16469        fullJavaBuilder.append(": TOTAL");
16470        if (totalMemtrack > 0) {
16471            fullJavaBuilder.append(" (");
16472            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16473            fullJavaBuilder.append(" memtrack)");
16474        } else {
16475        }
16476        fullJavaBuilder.append("\n");
16477
16478        MemInfoReader memInfo = new MemInfoReader();
16479        memInfo.readMemInfo();
16480        final long[] infos = memInfo.getRawInfo();
16481
16482        StringBuilder memInfoBuilder = new StringBuilder(1024);
16483        Debug.getMemInfo(infos);
16484        memInfoBuilder.append("  MemInfo: ");
16485        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16486        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16487        memInfoBuilder.append(stringifyKBSize(
16488                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16489        memInfoBuilder.append(stringifyKBSize(
16490                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16491        memInfoBuilder.append(stringifyKBSize(
16492                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16493        memInfoBuilder.append("           ");
16494        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16495        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16496        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16497        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16498        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16499            memInfoBuilder.append("  ZRAM: ");
16500            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16501            memInfoBuilder.append(" RAM, ");
16502            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16503            memInfoBuilder.append(" swap total, ");
16504            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16505            memInfoBuilder.append(" swap free\n");
16506        }
16507        final long[] ksm = getKsmInfo();
16508        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16509                || ksm[KSM_VOLATILE] != 0) {
16510            memInfoBuilder.append("  KSM: ");
16511            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16512            memInfoBuilder.append(" saved from shared ");
16513            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16514            memInfoBuilder.append("\n       ");
16515            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16516            memInfoBuilder.append(" unshared; ");
16517            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16518            memInfoBuilder.append(" volatile\n");
16519        }
16520        memInfoBuilder.append("  Free RAM: ");
16521        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16522                + memInfo.getFreeSizeKb()));
16523        memInfoBuilder.append("\n");
16524        memInfoBuilder.append("  Used RAM: ");
16525        memInfoBuilder.append(stringifyKBSize(
16526                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16527        memInfoBuilder.append("\n");
16528        memInfoBuilder.append("  Lost RAM: ");
16529        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16530                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16531                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16532        memInfoBuilder.append("\n");
16533        Slog.i(TAG, "Low on memory:");
16534        Slog.i(TAG, shortNativeBuilder.toString());
16535        Slog.i(TAG, fullJavaBuilder.toString());
16536        Slog.i(TAG, memInfoBuilder.toString());
16537
16538        StringBuilder dropBuilder = new StringBuilder(1024);
16539        /*
16540        StringWriter oomSw = new StringWriter();
16541        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16542        StringWriter catSw = new StringWriter();
16543        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16544        String[] emptyArgs = new String[] { };
16545        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16546        oomPw.flush();
16547        String oomString = oomSw.toString();
16548        */
16549        dropBuilder.append("Low on memory:");
16550        dropBuilder.append(stack);
16551        dropBuilder.append('\n');
16552        dropBuilder.append(fullNativeBuilder);
16553        dropBuilder.append(fullJavaBuilder);
16554        dropBuilder.append('\n');
16555        dropBuilder.append(memInfoBuilder);
16556        dropBuilder.append('\n');
16557        /*
16558        dropBuilder.append(oomString);
16559        dropBuilder.append('\n');
16560        */
16561        StringWriter catSw = new StringWriter();
16562        synchronized (ActivityManagerService.this) {
16563            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16564            String[] emptyArgs = new String[] { };
16565            catPw.println();
16566            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16567            catPw.println();
16568            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16569                    false, null).dumpLocked();
16570            catPw.println();
16571            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16572            catPw.flush();
16573        }
16574        dropBuilder.append(catSw.toString());
16575        addErrorToDropBox("lowmem", null, "system_server", null,
16576                null, tag.toString(), dropBuilder.toString(), null, null);
16577        //Slog.i(TAG, "Sent to dropbox:");
16578        //Slog.i(TAG, dropBuilder.toString());
16579        synchronized (ActivityManagerService.this) {
16580            long now = SystemClock.uptimeMillis();
16581            if (mLastMemUsageReportTime < now) {
16582                mLastMemUsageReportTime = now;
16583            }
16584        }
16585    }
16586
16587    /**
16588     * Searches array of arguments for the specified string
16589     * @param args array of argument strings
16590     * @param value value to search for
16591     * @return true if the value is contained in the array
16592     */
16593    private static boolean scanArgs(String[] args, String value) {
16594        if (args != null) {
16595            for (String arg : args) {
16596                if (value.equals(arg)) {
16597                    return true;
16598                }
16599            }
16600        }
16601        return false;
16602    }
16603
16604    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16605            ContentProviderRecord cpr, boolean always) {
16606        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16607
16608        if (!inLaunching || always) {
16609            synchronized (cpr) {
16610                cpr.launchingApp = null;
16611                cpr.notifyAll();
16612            }
16613            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16614            String names[] = cpr.info.authority.split(";");
16615            for (int j = 0; j < names.length; j++) {
16616                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16617            }
16618        }
16619
16620        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16621            ContentProviderConnection conn = cpr.connections.get(i);
16622            if (conn.waiting) {
16623                // If this connection is waiting for the provider, then we don't
16624                // need to mess with its process unless we are always removing
16625                // or for some reason the provider is not currently launching.
16626                if (inLaunching && !always) {
16627                    continue;
16628                }
16629            }
16630            ProcessRecord capp = conn.client;
16631            conn.dead = true;
16632            if (conn.stableCount > 0) {
16633                if (!capp.persistent && capp.thread != null
16634                        && capp.pid != 0
16635                        && capp.pid != MY_PID) {
16636                    capp.kill("depends on provider "
16637                            + cpr.name.flattenToShortString()
16638                            + " in dying proc " + (proc != null ? proc.processName : "??")
16639                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16640                }
16641            } else if (capp.thread != null && conn.provider.provider != null) {
16642                try {
16643                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16644                } catch (RemoteException e) {
16645                }
16646                // In the protocol here, we don't expect the client to correctly
16647                // clean up this connection, we'll just remove it.
16648                cpr.connections.remove(i);
16649                if (conn.client.conProviders.remove(conn)) {
16650                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16651                }
16652            }
16653        }
16654
16655        if (inLaunching && always) {
16656            mLaunchingProviders.remove(cpr);
16657        }
16658        return inLaunching;
16659    }
16660
16661    /**
16662     * Main code for cleaning up a process when it has gone away.  This is
16663     * called both as a result of the process dying, or directly when stopping
16664     * a process when running in single process mode.
16665     *
16666     * @return Returns true if the given process has been restarted, so the
16667     * app that was passed in must remain on the process lists.
16668     */
16669    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16670            boolean restarting, boolean allowRestart, int index) {
16671        if (index >= 0) {
16672            removeLruProcessLocked(app);
16673            ProcessList.remove(app.pid);
16674        }
16675
16676        mProcessesToGc.remove(app);
16677        mPendingPssProcesses.remove(app);
16678
16679        // Dismiss any open dialogs.
16680        if (app.crashDialog != null && !app.forceCrashReport) {
16681            app.crashDialog.dismiss();
16682            app.crashDialog = null;
16683        }
16684        if (app.anrDialog != null) {
16685            app.anrDialog.dismiss();
16686            app.anrDialog = null;
16687        }
16688        if (app.waitDialog != null) {
16689            app.waitDialog.dismiss();
16690            app.waitDialog = null;
16691        }
16692
16693        app.crashing = false;
16694        app.notResponding = false;
16695
16696        app.resetPackageList(mProcessStats);
16697        app.unlinkDeathRecipient();
16698        app.makeInactive(mProcessStats);
16699        app.waitingToKill = null;
16700        app.forcingToForeground = null;
16701        updateProcessForegroundLocked(app, false, false);
16702        app.foregroundActivities = false;
16703        app.hasShownUi = false;
16704        app.treatLikeActivity = false;
16705        app.hasAboveClient = false;
16706        app.hasClientActivities = false;
16707
16708        mServices.killServicesLocked(app, allowRestart);
16709
16710        boolean restart = false;
16711
16712        // Remove published content providers.
16713        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16714            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16715            final boolean always = app.bad || !allowRestart;
16716            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16717            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16718                // We left the provider in the launching list, need to
16719                // restart it.
16720                restart = true;
16721            }
16722
16723            cpr.provider = null;
16724            cpr.proc = null;
16725        }
16726        app.pubProviders.clear();
16727
16728        // Take care of any launching providers waiting for this process.
16729        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16730            restart = true;
16731        }
16732
16733        // Unregister from connected content providers.
16734        if (!app.conProviders.isEmpty()) {
16735            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16736                ContentProviderConnection conn = app.conProviders.get(i);
16737                conn.provider.connections.remove(conn);
16738                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16739                        conn.provider.name);
16740            }
16741            app.conProviders.clear();
16742        }
16743
16744        // At this point there may be remaining entries in mLaunchingProviders
16745        // where we were the only one waiting, so they are no longer of use.
16746        // Look for these and clean up if found.
16747        // XXX Commented out for now.  Trying to figure out a way to reproduce
16748        // the actual situation to identify what is actually going on.
16749        if (false) {
16750            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16751                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16752                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16753                    synchronized (cpr) {
16754                        cpr.launchingApp = null;
16755                        cpr.notifyAll();
16756                    }
16757                }
16758            }
16759        }
16760
16761        skipCurrentReceiverLocked(app);
16762
16763        // Unregister any receivers.
16764        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16765            removeReceiverLocked(app.receivers.valueAt(i));
16766        }
16767        app.receivers.clear();
16768
16769        // If the app is undergoing backup, tell the backup manager about it
16770        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16771            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16772                    + mBackupTarget.appInfo + " died during backup");
16773            try {
16774                IBackupManager bm = IBackupManager.Stub.asInterface(
16775                        ServiceManager.getService(Context.BACKUP_SERVICE));
16776                bm.agentDisconnected(app.info.packageName);
16777            } catch (RemoteException e) {
16778                // can't happen; backup manager is local
16779            }
16780        }
16781
16782        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16783            ProcessChangeItem item = mPendingProcessChanges.get(i);
16784            if (item.pid == app.pid) {
16785                mPendingProcessChanges.remove(i);
16786                mAvailProcessChanges.add(item);
16787            }
16788        }
16789        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16790                null).sendToTarget();
16791
16792        // If the caller is restarting this app, then leave it in its
16793        // current lists and let the caller take care of it.
16794        if (restarting) {
16795            return false;
16796        }
16797
16798        if (!app.persistent || app.isolated) {
16799            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16800                    "Removing non-persistent process during cleanup: " + app);
16801            removeProcessNameLocked(app.processName, app.uid);
16802            if (mHeavyWeightProcess == app) {
16803                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16804                        mHeavyWeightProcess.userId, 0));
16805                mHeavyWeightProcess = null;
16806            }
16807        } else if (!app.removed) {
16808            // This app is persistent, so we need to keep its record around.
16809            // If it is not already on the pending app list, add it there
16810            // and start a new process for it.
16811            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16812                mPersistentStartingProcesses.add(app);
16813                restart = true;
16814            }
16815        }
16816        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16817                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16818        mProcessesOnHold.remove(app);
16819
16820        if (app == mHomeProcess) {
16821            mHomeProcess = null;
16822        }
16823        if (app == mPreviousProcess) {
16824            mPreviousProcess = null;
16825        }
16826
16827        if (restart && !app.isolated) {
16828            // We have components that still need to be running in the
16829            // process, so re-launch it.
16830            if (index < 0) {
16831                ProcessList.remove(app.pid);
16832            }
16833            addProcessNameLocked(app);
16834            startProcessLocked(app, "restart", app.processName);
16835            return true;
16836        } else if (app.pid > 0 && app.pid != MY_PID) {
16837            // Goodbye!
16838            boolean removed;
16839            synchronized (mPidsSelfLocked) {
16840                mPidsSelfLocked.remove(app.pid);
16841                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16842            }
16843            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16844            if (app.isolated) {
16845                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16846            }
16847            app.setPid(0);
16848        }
16849        return false;
16850    }
16851
16852    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16853        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16854            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16855            if (cpr.launchingApp == app) {
16856                return true;
16857            }
16858        }
16859        return false;
16860    }
16861
16862    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16863        // Look through the content providers we are waiting to have launched,
16864        // and if any run in this process then either schedule a restart of
16865        // the process or kill the client waiting for it if this process has
16866        // gone bad.
16867        boolean restart = false;
16868        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16869            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16870            if (cpr.launchingApp == app) {
16871                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16872                    restart = true;
16873                } else {
16874                    removeDyingProviderLocked(app, cpr, true);
16875                }
16876            }
16877        }
16878        return restart;
16879    }
16880
16881    // =========================================================
16882    // SERVICES
16883    // =========================================================
16884
16885    @Override
16886    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16887            int flags) {
16888        enforceNotIsolatedCaller("getServices");
16889        synchronized (this) {
16890            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16891        }
16892    }
16893
16894    @Override
16895    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16896        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16897        synchronized (this) {
16898            return mServices.getRunningServiceControlPanelLocked(name);
16899        }
16900    }
16901
16902    @Override
16903    public ComponentName startService(IApplicationThread caller, Intent service,
16904            String resolvedType, String callingPackage, int userId)
16905            throws TransactionTooLargeException {
16906        enforceNotIsolatedCaller("startService");
16907        // Refuse possible leaked file descriptors
16908        if (service != null && service.hasFileDescriptors() == true) {
16909            throw new IllegalArgumentException("File descriptors passed in Intent");
16910        }
16911
16912        if (callingPackage == null) {
16913            throw new IllegalArgumentException("callingPackage cannot be null");
16914        }
16915
16916        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16917                "startService: " + service + " type=" + resolvedType);
16918        synchronized(this) {
16919            final int callingPid = Binder.getCallingPid();
16920            final int callingUid = Binder.getCallingUid();
16921            final long origId = Binder.clearCallingIdentity();
16922            ComponentName res = mServices.startServiceLocked(caller, service,
16923                    resolvedType, callingPid, callingUid, callingPackage, userId);
16924            Binder.restoreCallingIdentity(origId);
16925            return res;
16926        }
16927    }
16928
16929    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16930            String callingPackage, int userId)
16931            throws TransactionTooLargeException {
16932        synchronized(this) {
16933            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16934                    "startServiceInPackage: " + service + " type=" + resolvedType);
16935            final long origId = Binder.clearCallingIdentity();
16936            ComponentName res = mServices.startServiceLocked(null, service,
16937                    resolvedType, -1, uid, callingPackage, userId);
16938            Binder.restoreCallingIdentity(origId);
16939            return res;
16940        }
16941    }
16942
16943    @Override
16944    public int stopService(IApplicationThread caller, Intent service,
16945            String resolvedType, int userId) {
16946        enforceNotIsolatedCaller("stopService");
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        synchronized(this) {
16953            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16954        }
16955    }
16956
16957    @Override
16958    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16959        enforceNotIsolatedCaller("peekService");
16960        // Refuse possible leaked file descriptors
16961        if (service != null && service.hasFileDescriptors() == true) {
16962            throw new IllegalArgumentException("File descriptors passed in Intent");
16963        }
16964
16965        if (callingPackage == null) {
16966            throw new IllegalArgumentException("callingPackage cannot be null");
16967        }
16968
16969        synchronized(this) {
16970            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16971        }
16972    }
16973
16974    @Override
16975    public boolean stopServiceToken(ComponentName className, IBinder token,
16976            int startId) {
16977        synchronized(this) {
16978            return mServices.stopServiceTokenLocked(className, token, startId);
16979        }
16980    }
16981
16982    @Override
16983    public void setServiceForeground(ComponentName className, IBinder token,
16984            int id, Notification notification, int flags) {
16985        synchronized(this) {
16986            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16987        }
16988    }
16989
16990    @Override
16991    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16992            boolean requireFull, String name, String callerPackage) {
16993        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16994                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16995    }
16996
16997    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16998            String className, int flags) {
16999        boolean result = false;
17000        // For apps that don't have pre-defined UIDs, check for permission
17001        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17002            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17003                if (ActivityManager.checkUidPermission(
17004                        INTERACT_ACROSS_USERS,
17005                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17006                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17007                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17008                            + " requests FLAG_SINGLE_USER, but app does not hold "
17009                            + INTERACT_ACROSS_USERS;
17010                    Slog.w(TAG, msg);
17011                    throw new SecurityException(msg);
17012                }
17013                // Permission passed
17014                result = true;
17015            }
17016        } else if ("system".equals(componentProcessName)) {
17017            result = true;
17018        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17019            // Phone app and persistent apps are allowed to export singleuser providers.
17020            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17021                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17022        }
17023        if (DEBUG_MU) Slog.v(TAG_MU,
17024                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17025                + Integer.toHexString(flags) + ") = " + result);
17026        return result;
17027    }
17028
17029    /**
17030     * Checks to see if the caller is in the same app as the singleton
17031     * component, or the component is in a special app. It allows special apps
17032     * to export singleton components but prevents exporting singleton
17033     * components for regular apps.
17034     */
17035    boolean isValidSingletonCall(int callingUid, int componentUid) {
17036        int componentAppId = UserHandle.getAppId(componentUid);
17037        return UserHandle.isSameApp(callingUid, componentUid)
17038                || componentAppId == Process.SYSTEM_UID
17039                || componentAppId == Process.PHONE_UID
17040                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17041                        == PackageManager.PERMISSION_GRANTED;
17042    }
17043
17044    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17045            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17046            int userId) throws TransactionTooLargeException {
17047        enforceNotIsolatedCaller("bindService");
17048
17049        // Refuse possible leaked file descriptors
17050        if (service != null && service.hasFileDescriptors() == true) {
17051            throw new IllegalArgumentException("File descriptors passed in Intent");
17052        }
17053
17054        if (callingPackage == null) {
17055            throw new IllegalArgumentException("callingPackage cannot be null");
17056        }
17057
17058        synchronized(this) {
17059            return mServices.bindServiceLocked(caller, token, service,
17060                    resolvedType, connection, flags, callingPackage, userId);
17061        }
17062    }
17063
17064    public boolean unbindService(IServiceConnection connection) {
17065        synchronized (this) {
17066            return mServices.unbindServiceLocked(connection);
17067        }
17068    }
17069
17070    public void publishService(IBinder token, Intent intent, IBinder service) {
17071        // Refuse possible leaked file descriptors
17072        if (intent != null && intent.hasFileDescriptors() == true) {
17073            throw new IllegalArgumentException("File descriptors passed in Intent");
17074        }
17075
17076        synchronized(this) {
17077            if (!(token instanceof ServiceRecord)) {
17078                throw new IllegalArgumentException("Invalid service token");
17079            }
17080            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17081        }
17082    }
17083
17084    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17085        // Refuse possible leaked file descriptors
17086        if (intent != null && intent.hasFileDescriptors() == true) {
17087            throw new IllegalArgumentException("File descriptors passed in Intent");
17088        }
17089
17090        synchronized(this) {
17091            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17092        }
17093    }
17094
17095    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17096        synchronized(this) {
17097            if (!(token instanceof ServiceRecord)) {
17098                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17099                throw new IllegalArgumentException("Invalid service token");
17100            }
17101            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17102        }
17103    }
17104
17105    // =========================================================
17106    // BACKUP AND RESTORE
17107    // =========================================================
17108
17109    // Cause the target app to be launched if necessary and its backup agent
17110    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17111    // activity manager to announce its creation.
17112    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17113        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17114        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17115
17116        IPackageManager pm = AppGlobals.getPackageManager();
17117        ApplicationInfo app = null;
17118        try {
17119            app = pm.getApplicationInfo(packageName, 0, userId);
17120        } catch (RemoteException e) {
17121            // can't happen; package manager is process-local
17122        }
17123        if (app == null) {
17124            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17125            return false;
17126        }
17127
17128        synchronized(this) {
17129            // !!! TODO: currently no check here that we're already bound
17130            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17131            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17132            synchronized (stats) {
17133                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17134            }
17135
17136            // Backup agent is now in use, its package can't be stopped.
17137            try {
17138                AppGlobals.getPackageManager().setPackageStoppedState(
17139                        app.packageName, false, UserHandle.getUserId(app.uid));
17140            } catch (RemoteException e) {
17141            } catch (IllegalArgumentException e) {
17142                Slog.w(TAG, "Failed trying to unstop package "
17143                        + app.packageName + ": " + e);
17144            }
17145
17146            BackupRecord r = new BackupRecord(ss, app, backupMode);
17147            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17148                    ? new ComponentName(app.packageName, app.backupAgentName)
17149                    : new ComponentName("android", "FullBackupAgent");
17150            // startProcessLocked() returns existing proc's record if it's already running
17151            ProcessRecord proc = startProcessLocked(app.processName, app,
17152                    false, 0, "backup", hostingName, false, false, false);
17153            if (proc == null) {
17154                Slog.e(TAG, "Unable to start backup agent process " + r);
17155                return false;
17156            }
17157
17158            // If the app is a regular app (uid >= 10000) and not the system server or phone
17159            // process, etc, then mark it as being in full backup so that certain calls to the
17160            // process can be blocked. This is not reset to false anywhere because we kill the
17161            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17162            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17163                proc.inFullBackup = true;
17164            }
17165            r.app = proc;
17166            mBackupTarget = r;
17167            mBackupAppName = app.packageName;
17168
17169            // Try not to kill the process during backup
17170            updateOomAdjLocked(proc);
17171
17172            // If the process is already attached, schedule the creation of the backup agent now.
17173            // If it is not yet live, this will be done when it attaches to the framework.
17174            if (proc.thread != null) {
17175                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17176                try {
17177                    proc.thread.scheduleCreateBackupAgent(app,
17178                            compatibilityInfoForPackageLocked(app), backupMode);
17179                } catch (RemoteException e) {
17180                    // Will time out on the backup manager side
17181                }
17182            } else {
17183                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17184            }
17185            // Invariants: at this point, the target app process exists and the application
17186            // is either already running or in the process of coming up.  mBackupTarget and
17187            // mBackupAppName describe the app, so that when it binds back to the AM we
17188            // know that it's scheduled for a backup-agent operation.
17189        }
17190
17191        return true;
17192    }
17193
17194    @Override
17195    public void clearPendingBackup() {
17196        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17197        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17198
17199        synchronized (this) {
17200            mBackupTarget = null;
17201            mBackupAppName = null;
17202        }
17203    }
17204
17205    // A backup agent has just come up
17206    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17207        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17208                + " = " + agent);
17209
17210        synchronized(this) {
17211            if (!agentPackageName.equals(mBackupAppName)) {
17212                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17213                return;
17214            }
17215        }
17216
17217        long oldIdent = Binder.clearCallingIdentity();
17218        try {
17219            IBackupManager bm = IBackupManager.Stub.asInterface(
17220                    ServiceManager.getService(Context.BACKUP_SERVICE));
17221            bm.agentConnected(agentPackageName, agent);
17222        } catch (RemoteException e) {
17223            // can't happen; the backup manager service is local
17224        } catch (Exception e) {
17225            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17226            e.printStackTrace();
17227        } finally {
17228            Binder.restoreCallingIdentity(oldIdent);
17229        }
17230    }
17231
17232    // done with this agent
17233    public void unbindBackupAgent(ApplicationInfo appInfo) {
17234        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17235        if (appInfo == null) {
17236            Slog.w(TAG, "unbind backup agent for null app");
17237            return;
17238        }
17239
17240        synchronized(this) {
17241            try {
17242                if (mBackupAppName == null) {
17243                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17244                    return;
17245                }
17246
17247                if (!mBackupAppName.equals(appInfo.packageName)) {
17248                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17249                    return;
17250                }
17251
17252                // Not backing this app up any more; reset its OOM adjustment
17253                final ProcessRecord proc = mBackupTarget.app;
17254                updateOomAdjLocked(proc);
17255
17256                // If the app crashed during backup, 'thread' will be null here
17257                if (proc.thread != null) {
17258                    try {
17259                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17260                                compatibilityInfoForPackageLocked(appInfo));
17261                    } catch (Exception e) {
17262                        Slog.e(TAG, "Exception when unbinding backup agent:");
17263                        e.printStackTrace();
17264                    }
17265                }
17266            } finally {
17267                mBackupTarget = null;
17268                mBackupAppName = null;
17269            }
17270        }
17271    }
17272    // =========================================================
17273    // BROADCASTS
17274    // =========================================================
17275
17276    boolean isPendingBroadcastProcessLocked(int pid) {
17277        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17278                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17279    }
17280
17281    void skipPendingBroadcastLocked(int pid) {
17282            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17283            for (BroadcastQueue queue : mBroadcastQueues) {
17284                queue.skipPendingBroadcastLocked(pid);
17285            }
17286    }
17287
17288    // The app just attached; send any pending broadcasts that it should receive
17289    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17290        boolean didSomething = false;
17291        for (BroadcastQueue queue : mBroadcastQueues) {
17292            didSomething |= queue.sendPendingBroadcastsLocked(app);
17293        }
17294        return didSomething;
17295    }
17296
17297    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17298            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17299        enforceNotIsolatedCaller("registerReceiver");
17300        ArrayList<Intent> stickyIntents = null;
17301        ProcessRecord callerApp = null;
17302        int callingUid;
17303        int callingPid;
17304        synchronized(this) {
17305            if (caller != null) {
17306                callerApp = getRecordForAppLocked(caller);
17307                if (callerApp == null) {
17308                    throw new SecurityException(
17309                            "Unable to find app for caller " + caller
17310                            + " (pid=" + Binder.getCallingPid()
17311                            + ") when registering receiver " + receiver);
17312                }
17313                if (callerApp.info.uid != Process.SYSTEM_UID &&
17314                        !callerApp.pkgList.containsKey(callerPackage) &&
17315                        !"android".equals(callerPackage)) {
17316                    throw new SecurityException("Given caller package " + callerPackage
17317                            + " is not running in process " + callerApp);
17318                }
17319                callingUid = callerApp.info.uid;
17320                callingPid = callerApp.pid;
17321            } else {
17322                callerPackage = null;
17323                callingUid = Binder.getCallingUid();
17324                callingPid = Binder.getCallingPid();
17325            }
17326
17327            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17328                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17329
17330            Iterator<String> actions = filter.actionsIterator();
17331            if (actions == null) {
17332                ArrayList<String> noAction = new ArrayList<String>(1);
17333                noAction.add(null);
17334                actions = noAction.iterator();
17335            }
17336
17337            // Collect stickies of users
17338            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17339            while (actions.hasNext()) {
17340                String action = actions.next();
17341                for (int id : userIds) {
17342                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17343                    if (stickies != null) {
17344                        ArrayList<Intent> intents = stickies.get(action);
17345                        if (intents != null) {
17346                            if (stickyIntents == null) {
17347                                stickyIntents = new ArrayList<Intent>();
17348                            }
17349                            stickyIntents.addAll(intents);
17350                        }
17351                    }
17352                }
17353            }
17354        }
17355
17356        ArrayList<Intent> allSticky = null;
17357        if (stickyIntents != null) {
17358            final ContentResolver resolver = mContext.getContentResolver();
17359            // Look for any matching sticky broadcasts...
17360            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17361                Intent intent = stickyIntents.get(i);
17362                // If intent has scheme "content", it will need to acccess
17363                // provider that needs to lock mProviderMap in ActivityThread
17364                // and also it may need to wait application response, so we
17365                // cannot lock ActivityManagerService here.
17366                if (filter.match(resolver, intent, true, TAG) >= 0) {
17367                    if (allSticky == null) {
17368                        allSticky = new ArrayList<Intent>();
17369                    }
17370                    allSticky.add(intent);
17371                }
17372            }
17373        }
17374
17375        // The first sticky in the list is returned directly back to the client.
17376        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17377        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17378        if (receiver == null) {
17379            return sticky;
17380        }
17381
17382        synchronized (this) {
17383            if (callerApp != null && (callerApp.thread == null
17384                    || callerApp.thread.asBinder() != caller.asBinder())) {
17385                // Original caller already died
17386                return null;
17387            }
17388            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17389            if (rl == null) {
17390                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17391                        userId, receiver);
17392                if (rl.app != null) {
17393                    rl.app.receivers.add(rl);
17394                } else {
17395                    try {
17396                        receiver.asBinder().linkToDeath(rl, 0);
17397                    } catch (RemoteException e) {
17398                        return sticky;
17399                    }
17400                    rl.linkedToDeath = true;
17401                }
17402                mRegisteredReceivers.put(receiver.asBinder(), rl);
17403            } else if (rl.uid != callingUid) {
17404                throw new IllegalArgumentException(
17405                        "Receiver requested to register for uid " + callingUid
17406                        + " was previously registered for uid " + rl.uid);
17407            } else if (rl.pid != callingPid) {
17408                throw new IllegalArgumentException(
17409                        "Receiver requested to register for pid " + callingPid
17410                        + " was previously registered for pid " + rl.pid);
17411            } else if (rl.userId != userId) {
17412                throw new IllegalArgumentException(
17413                        "Receiver requested to register for user " + userId
17414                        + " was previously registered for user " + rl.userId);
17415            }
17416            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17417                    permission, callingUid, userId);
17418            rl.add(bf);
17419            if (!bf.debugCheck()) {
17420                Slog.w(TAG, "==> For Dynamic broadcast");
17421            }
17422            mReceiverResolver.addFilter(bf);
17423
17424            // Enqueue broadcasts for all existing stickies that match
17425            // this filter.
17426            if (allSticky != null) {
17427                ArrayList receivers = new ArrayList();
17428                receivers.add(bf);
17429
17430                final int stickyCount = allSticky.size();
17431                for (int i = 0; i < stickyCount; i++) {
17432                    Intent intent = allSticky.get(i);
17433                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17434                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17435                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17436                            null, 0, null, null, false, true, true, -1);
17437                    queue.enqueueParallelBroadcastLocked(r);
17438                    queue.scheduleBroadcastsLocked();
17439                }
17440            }
17441
17442            return sticky;
17443        }
17444    }
17445
17446    public void unregisterReceiver(IIntentReceiver receiver) {
17447        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17448
17449        final long origId = Binder.clearCallingIdentity();
17450        try {
17451            boolean doTrim = false;
17452
17453            synchronized(this) {
17454                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17455                if (rl != null) {
17456                    final BroadcastRecord r = rl.curBroadcast;
17457                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17458                        final boolean doNext = r.queue.finishReceiverLocked(
17459                                r, r.resultCode, r.resultData, r.resultExtras,
17460                                r.resultAbort, false);
17461                        if (doNext) {
17462                            doTrim = true;
17463                            r.queue.processNextBroadcast(false);
17464                        }
17465                    }
17466
17467                    if (rl.app != null) {
17468                        rl.app.receivers.remove(rl);
17469                    }
17470                    removeReceiverLocked(rl);
17471                    if (rl.linkedToDeath) {
17472                        rl.linkedToDeath = false;
17473                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17474                    }
17475                }
17476            }
17477
17478            // If we actually concluded any broadcasts, we might now be able
17479            // to trim the recipients' apps from our working set
17480            if (doTrim) {
17481                trimApplications();
17482                return;
17483            }
17484
17485        } finally {
17486            Binder.restoreCallingIdentity(origId);
17487        }
17488    }
17489
17490    void removeReceiverLocked(ReceiverList rl) {
17491        mRegisteredReceivers.remove(rl.receiver.asBinder());
17492        for (int i = rl.size() - 1; i >= 0; i--) {
17493            mReceiverResolver.removeFilter(rl.get(i));
17494        }
17495    }
17496
17497    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17498        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17499            ProcessRecord r = mLruProcesses.get(i);
17500            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17501                try {
17502                    r.thread.dispatchPackageBroadcast(cmd, packages);
17503                } catch (RemoteException ex) {
17504                }
17505            }
17506        }
17507    }
17508
17509    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17510            int callingUid, int[] users) {
17511        // TODO: come back and remove this assumption to triage all broadcasts
17512        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17513
17514        List<ResolveInfo> receivers = null;
17515        try {
17516            HashSet<ComponentName> singleUserReceivers = null;
17517            boolean scannedFirstReceivers = false;
17518            for (int user : users) {
17519                // Skip users that have Shell restrictions, with exception of always permitted
17520                // Shell broadcasts
17521                if (callingUid == Process.SHELL_UID
17522                        && mUserController.hasUserRestriction(
17523                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17524                        && !isPermittedShellBroadcast(intent)) {
17525                    continue;
17526                }
17527                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17528                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17529                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17530                    // If this is not the system user, we need to check for
17531                    // any receivers that should be filtered out.
17532                    for (int i=0; i<newReceivers.size(); i++) {
17533                        ResolveInfo ri = newReceivers.get(i);
17534                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17535                            newReceivers.remove(i);
17536                            i--;
17537                        }
17538                    }
17539                }
17540                if (newReceivers != null && newReceivers.size() == 0) {
17541                    newReceivers = null;
17542                }
17543                if (receivers == null) {
17544                    receivers = newReceivers;
17545                } else if (newReceivers != null) {
17546                    // We need to concatenate the additional receivers
17547                    // found with what we have do far.  This would be easy,
17548                    // but we also need to de-dup any receivers that are
17549                    // singleUser.
17550                    if (!scannedFirstReceivers) {
17551                        // Collect any single user receivers we had already retrieved.
17552                        scannedFirstReceivers = true;
17553                        for (int i=0; i<receivers.size(); i++) {
17554                            ResolveInfo ri = receivers.get(i);
17555                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17556                                ComponentName cn = new ComponentName(
17557                                        ri.activityInfo.packageName, ri.activityInfo.name);
17558                                if (singleUserReceivers == null) {
17559                                    singleUserReceivers = new HashSet<ComponentName>();
17560                                }
17561                                singleUserReceivers.add(cn);
17562                            }
17563                        }
17564                    }
17565                    // Add the new results to the existing results, tracking
17566                    // and de-dupping single user receivers.
17567                    for (int i=0; i<newReceivers.size(); i++) {
17568                        ResolveInfo ri = newReceivers.get(i);
17569                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17570                            ComponentName cn = new ComponentName(
17571                                    ri.activityInfo.packageName, ri.activityInfo.name);
17572                            if (singleUserReceivers == null) {
17573                                singleUserReceivers = new HashSet<ComponentName>();
17574                            }
17575                            if (!singleUserReceivers.contains(cn)) {
17576                                singleUserReceivers.add(cn);
17577                                receivers.add(ri);
17578                            }
17579                        } else {
17580                            receivers.add(ri);
17581                        }
17582                    }
17583                }
17584            }
17585        } catch (RemoteException ex) {
17586            // pm is in same process, this will never happen.
17587        }
17588        return receivers;
17589    }
17590
17591    private boolean isPermittedShellBroadcast(Intent intent) {
17592        // remote bugreport should always be allowed to be taken
17593        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17594    }
17595
17596    final int broadcastIntentLocked(ProcessRecord callerApp,
17597            String callerPackage, Intent intent, String resolvedType,
17598            IIntentReceiver resultTo, int resultCode, String resultData,
17599            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17600            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17601        intent = new Intent(intent);
17602
17603        // By default broadcasts do not go to stopped apps.
17604        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17605
17606        // If we have not finished booting, don't allow this to launch new processes.
17607        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17608            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17609        }
17610
17611        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17612                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17613                + " ordered=" + ordered + " userid=" + userId);
17614        if ((resultTo != null) && !ordered) {
17615            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17616        }
17617
17618        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17619                ALLOW_NON_FULL, "broadcast", callerPackage);
17620
17621        // Make sure that the user who is receiving this broadcast is running.
17622        // If not, we will just skip it. Make an exception for shutdown broadcasts
17623        // and upgrade steps.
17624
17625        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17626            if ((callingUid != Process.SYSTEM_UID
17627                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17628                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17629                Slog.w(TAG, "Skipping broadcast of " + intent
17630                        + ": user " + userId + " is stopped");
17631                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17632            }
17633        }
17634
17635        BroadcastOptions brOptions = null;
17636        if (bOptions != null) {
17637            brOptions = new BroadcastOptions(bOptions);
17638            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17639                // See if the caller is allowed to do this.  Note we are checking against
17640                // the actual real caller (not whoever provided the operation as say a
17641                // PendingIntent), because that who is actually supplied the arguments.
17642                if (checkComponentPermission(
17643                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17644                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17645                        != PackageManager.PERMISSION_GRANTED) {
17646                    String msg = "Permission Denial: " + intent.getAction()
17647                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17648                            + ", uid=" + callingUid + ")"
17649                            + " requires "
17650                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17651                    Slog.w(TAG, msg);
17652                    throw new SecurityException(msg);
17653                }
17654            }
17655        }
17656
17657        // Verify that protected broadcasts are only being sent by system code,
17658        // and that system code is only sending protected broadcasts.
17659        final String action = intent.getAction();
17660        final boolean isProtectedBroadcast;
17661        try {
17662            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17663        } catch (RemoteException e) {
17664            Slog.w(TAG, "Remote exception", e);
17665            return ActivityManager.BROADCAST_SUCCESS;
17666        }
17667
17668        final boolean isCallerSystem;
17669        switch (UserHandle.getAppId(callingUid)) {
17670            case Process.ROOT_UID:
17671            case Process.SYSTEM_UID:
17672            case Process.PHONE_UID:
17673            case Process.BLUETOOTH_UID:
17674            case Process.NFC_UID:
17675                isCallerSystem = true;
17676                break;
17677            default:
17678                isCallerSystem = (callerApp != null) && callerApp.persistent;
17679                break;
17680        }
17681
17682        if (isCallerSystem) {
17683            if (isProtectedBroadcast
17684                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17685                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17686                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17687                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17688                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17689                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17690                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17691                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17692                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17693                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17694                // Broadcast is either protected, or it's a public action that
17695                // we've relaxed, so it's fine for system internals to send.
17696            } else {
17697                // The vast majority of broadcasts sent from system internals
17698                // should be protected to avoid security holes, so yell loudly
17699                // to ensure we examine these cases.
17700                if (callerApp != null) {
17701                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17702                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17703                            new Throwable());
17704                } else {
17705                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17706                            + " from system uid " + UserHandle.formatUid(callingUid)
17707                            + " pkg " + callerPackage,
17708                            new Throwable());
17709                }
17710            }
17711
17712        } else {
17713            if (isProtectedBroadcast) {
17714                String msg = "Permission Denial: not allowed to send broadcast "
17715                        + action + " from pid="
17716                        + callingPid + ", uid=" + callingUid;
17717                Slog.w(TAG, msg);
17718                throw new SecurityException(msg);
17719
17720            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17721                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17722                // Special case for compatibility: we don't want apps to send this,
17723                // but historically it has not been protected and apps may be using it
17724                // to poke their own app widget.  So, instead of making it protected,
17725                // just limit it to the caller.
17726                if (callerPackage == null) {
17727                    String msg = "Permission Denial: not allowed to send broadcast "
17728                            + action + " from unknown caller.";
17729                    Slog.w(TAG, msg);
17730                    throw new SecurityException(msg);
17731                } else if (intent.getComponent() != null) {
17732                    // They are good enough to send to an explicit component...  verify
17733                    // it is being sent to the calling app.
17734                    if (!intent.getComponent().getPackageName().equals(
17735                            callerPackage)) {
17736                        String msg = "Permission Denial: not allowed to send broadcast "
17737                                + action + " to "
17738                                + intent.getComponent().getPackageName() + " from "
17739                                + callerPackage;
17740                        Slog.w(TAG, msg);
17741                        throw new SecurityException(msg);
17742                    }
17743                } else {
17744                    // Limit broadcast to their own package.
17745                    intent.setPackage(callerPackage);
17746                }
17747            }
17748        }
17749
17750        if (action != null) {
17751            switch (action) {
17752                case Intent.ACTION_UID_REMOVED:
17753                case Intent.ACTION_PACKAGE_REMOVED:
17754                case Intent.ACTION_PACKAGE_CHANGED:
17755                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17756                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17757                case Intent.ACTION_PACKAGES_SUSPENDED:
17758                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17759                    // Handle special intents: if this broadcast is from the package
17760                    // manager about a package being removed, we need to remove all of
17761                    // its activities from the history stack.
17762                    if (checkComponentPermission(
17763                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17764                            callingPid, callingUid, -1, true)
17765                            != PackageManager.PERMISSION_GRANTED) {
17766                        String msg = "Permission Denial: " + intent.getAction()
17767                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17768                                + ", uid=" + callingUid + ")"
17769                                + " requires "
17770                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17771                        Slog.w(TAG, msg);
17772                        throw new SecurityException(msg);
17773                    }
17774                    switch (action) {
17775                        case Intent.ACTION_UID_REMOVED:
17776                            final Bundle intentExtras = intent.getExtras();
17777                            final int uid = intentExtras != null
17778                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17779                            if (uid >= 0) {
17780                                mBatteryStatsService.removeUid(uid);
17781                                mAppOpsService.uidRemoved(uid);
17782                            }
17783                            break;
17784                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17785                            // If resources are unavailable just force stop all those packages
17786                            // and flush the attribute cache as well.
17787                            String list[] =
17788                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17789                            if (list != null && list.length > 0) {
17790                                for (int i = 0; i < list.length; i++) {
17791                                    forceStopPackageLocked(list[i], -1, false, true, true,
17792                                            false, false, userId, "storage unmount");
17793                                }
17794                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17795                                sendPackageBroadcastLocked(
17796                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17797                                        userId);
17798                            }
17799                            break;
17800                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17801                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17802                            break;
17803                        case Intent.ACTION_PACKAGE_REMOVED:
17804                        case Intent.ACTION_PACKAGE_CHANGED:
17805                            Uri data = intent.getData();
17806                            String ssp;
17807                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17808                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17809                                final boolean replacing =
17810                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17811                                final boolean killProcess =
17812                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17813                                final boolean fullUninstall = removed && !replacing;
17814                                if (removed) {
17815                                    if (killProcess) {
17816                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17817                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17818                                                false, true, true, false, fullUninstall, userId,
17819                                                removed ? "pkg removed" : "pkg changed");
17820                                    }
17821                                    final int cmd = killProcess
17822                                            ? IApplicationThread.PACKAGE_REMOVED
17823                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17824                                    sendPackageBroadcastLocked(cmd,
17825                                            new String[] {ssp}, userId);
17826                                    if (fullUninstall) {
17827                                        mAppOpsService.packageRemoved(
17828                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17829
17830                                        // Remove all permissions granted from/to this package
17831                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17832
17833                                        removeTasksByPackageNameLocked(ssp, userId);
17834
17835                                        // Hide the "unsupported display" dialog if necessary.
17836                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17837                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17838                                            mUnsupportedDisplaySizeDialog.dismiss();
17839                                            mUnsupportedDisplaySizeDialog = null;
17840                                        }
17841                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17842                                        mBatteryStatsService.notePackageUninstalled(ssp);
17843                                    }
17844                                } else {
17845                                    if (killProcess) {
17846                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17847                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17848                                                userId, ProcessList.INVALID_ADJ,
17849                                                false, true, true, false, "change " + ssp);
17850                                    }
17851                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17852                                            intent.getStringArrayExtra(
17853                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17854                                }
17855                            }
17856                            break;
17857                        case Intent.ACTION_PACKAGES_SUSPENDED:
17858                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17859                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17860                                    intent.getAction());
17861                            final String[] packageNames = intent.getStringArrayExtra(
17862                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17863                            final int userHandle = intent.getIntExtra(
17864                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17865
17866                            synchronized(ActivityManagerService.this) {
17867                                mRecentTasks.onPackagesSuspendedChanged(
17868                                        packageNames, suspended, userHandle);
17869                            }
17870                            break;
17871                    }
17872                    break;
17873                case Intent.ACTION_PACKAGE_REPLACED:
17874                {
17875                    final Uri data = intent.getData();
17876                    final String ssp;
17877                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17878                        final ApplicationInfo aInfo =
17879                                getPackageManagerInternalLocked().getApplicationInfo(
17880                                        ssp,
17881                                        userId);
17882                        if (aInfo == null) {
17883                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17884                                    + " ssp=" + ssp + " data=" + data);
17885                            return ActivityManager.BROADCAST_SUCCESS;
17886                        }
17887                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17888                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17889                                new String[] {ssp}, userId);
17890                    }
17891                    break;
17892                }
17893                case Intent.ACTION_PACKAGE_ADDED:
17894                {
17895                    // Special case for adding a package: by default turn on compatibility mode.
17896                    Uri data = intent.getData();
17897                    String ssp;
17898                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17899                        final boolean replacing =
17900                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17901                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17902
17903                        try {
17904                            ApplicationInfo ai = AppGlobals.getPackageManager().
17905                                    getApplicationInfo(ssp, 0, 0);
17906                            mBatteryStatsService.notePackageInstalled(ssp,
17907                                    ai != null ? ai.versionCode : 0);
17908                        } catch (RemoteException e) {
17909                        }
17910                    }
17911                    break;
17912                }
17913                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17914                {
17915                    Uri data = intent.getData();
17916                    String ssp;
17917                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17918                        // Hide the "unsupported display" dialog if necessary.
17919                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17920                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17921                            mUnsupportedDisplaySizeDialog.dismiss();
17922                            mUnsupportedDisplaySizeDialog = null;
17923                        }
17924                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17925                    }
17926                    break;
17927                }
17928                case Intent.ACTION_TIMEZONE_CHANGED:
17929                    // If this is the time zone changed action, queue up a message that will reset
17930                    // the timezone of all currently running processes. This message will get
17931                    // queued up before the broadcast happens.
17932                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17933                    break;
17934                case Intent.ACTION_TIME_CHANGED:
17935                    // If the user set the time, let all running processes know.
17936                    final int is24Hour =
17937                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17938                                    : 0;
17939                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17940                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17941                    synchronized (stats) {
17942                        stats.noteCurrentTimeChangedLocked();
17943                    }
17944                    break;
17945                case Intent.ACTION_CLEAR_DNS_CACHE:
17946                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17947                    break;
17948                case Proxy.PROXY_CHANGE_ACTION:
17949                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17950                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17951                    break;
17952                case android.hardware.Camera.ACTION_NEW_PICTURE:
17953                case android.hardware.Camera.ACTION_NEW_VIDEO:
17954                    // These broadcasts are no longer allowed by the system, since they can
17955                    // cause significant thrashing at a crictical point (using the camera).
17956                    // Apps should use JobScehduler to monitor for media provider changes.
17957                    Slog.w(TAG, action + " no longer allowed; dropping from "
17958                            + UserHandle.formatUid(callingUid));
17959                    if (resultTo != null) {
17960                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17961                        try {
17962                            queue.performReceiveLocked(callerApp, resultTo, intent,
17963                                    Activity.RESULT_CANCELED, null, null,
17964                                    false, false, userId);
17965                        } catch (RemoteException e) {
17966                            Slog.w(TAG, "Failure ["
17967                                    + queue.mQueueName + "] sending broadcast result of "
17968                                    + intent, e);
17969
17970                        }
17971                    }
17972                    // Lie; we don't want to crash the app.
17973                    return ActivityManager.BROADCAST_SUCCESS;
17974            }
17975        }
17976
17977        // Add to the sticky list if requested.
17978        if (sticky) {
17979            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17980                    callingPid, callingUid)
17981                    != PackageManager.PERMISSION_GRANTED) {
17982                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17983                        + callingPid + ", uid=" + callingUid
17984                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17985                Slog.w(TAG, msg);
17986                throw new SecurityException(msg);
17987            }
17988            if (requiredPermissions != null && requiredPermissions.length > 0) {
17989                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17990                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17991                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17992            }
17993            if (intent.getComponent() != null) {
17994                throw new SecurityException(
17995                        "Sticky broadcasts can't target a specific component");
17996            }
17997            // We use userId directly here, since the "all" target is maintained
17998            // as a separate set of sticky broadcasts.
17999            if (userId != UserHandle.USER_ALL) {
18000                // But first, if this is not a broadcast to all users, then
18001                // make sure it doesn't conflict with an existing broadcast to
18002                // all users.
18003                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18004                        UserHandle.USER_ALL);
18005                if (stickies != null) {
18006                    ArrayList<Intent> list = stickies.get(intent.getAction());
18007                    if (list != null) {
18008                        int N = list.size();
18009                        int i;
18010                        for (i=0; i<N; i++) {
18011                            if (intent.filterEquals(list.get(i))) {
18012                                throw new IllegalArgumentException(
18013                                        "Sticky broadcast " + intent + " for user "
18014                                        + userId + " conflicts with existing global broadcast");
18015                            }
18016                        }
18017                    }
18018                }
18019            }
18020            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18021            if (stickies == null) {
18022                stickies = new ArrayMap<>();
18023                mStickyBroadcasts.put(userId, stickies);
18024            }
18025            ArrayList<Intent> list = stickies.get(intent.getAction());
18026            if (list == null) {
18027                list = new ArrayList<>();
18028                stickies.put(intent.getAction(), list);
18029            }
18030            final int stickiesCount = list.size();
18031            int i;
18032            for (i = 0; i < stickiesCount; i++) {
18033                if (intent.filterEquals(list.get(i))) {
18034                    // This sticky already exists, replace it.
18035                    list.set(i, new Intent(intent));
18036                    break;
18037                }
18038            }
18039            if (i >= stickiesCount) {
18040                list.add(new Intent(intent));
18041            }
18042        }
18043
18044        int[] users;
18045        if (userId == UserHandle.USER_ALL) {
18046            // Caller wants broadcast to go to all started users.
18047            users = mUserController.getStartedUserArrayLocked();
18048        } else {
18049            // Caller wants broadcast to go to one specific user.
18050            users = new int[] {userId};
18051        }
18052
18053        // Figure out who all will receive this broadcast.
18054        List receivers = null;
18055        List<BroadcastFilter> registeredReceivers = null;
18056        // Need to resolve the intent to interested receivers...
18057        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18058                 == 0) {
18059            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18060        }
18061        if (intent.getComponent() == null) {
18062            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18063                // Query one target user at a time, excluding shell-restricted users
18064                for (int i = 0; i < users.length; i++) {
18065                    if (mUserController.hasUserRestriction(
18066                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18067                        continue;
18068                    }
18069                    List<BroadcastFilter> registeredReceiversForUser =
18070                            mReceiverResolver.queryIntent(intent,
18071                                    resolvedType, false, users[i]);
18072                    if (registeredReceivers == null) {
18073                        registeredReceivers = registeredReceiversForUser;
18074                    } else if (registeredReceiversForUser != null) {
18075                        registeredReceivers.addAll(registeredReceiversForUser);
18076                    }
18077                }
18078            } else {
18079                registeredReceivers = mReceiverResolver.queryIntent(intent,
18080                        resolvedType, false, userId);
18081            }
18082        }
18083
18084        final boolean replacePending =
18085                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18086
18087        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18088                + " replacePending=" + replacePending);
18089
18090        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18091        if (!ordered && NR > 0) {
18092            // If we are not serializing this broadcast, then send the
18093            // registered receivers separately so they don't wait for the
18094            // components to be launched.
18095            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18096            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18097                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18098                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18099                    resultExtras, ordered, sticky, false, userId);
18100            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18101            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18102            if (!replaced) {
18103                queue.enqueueParallelBroadcastLocked(r);
18104                queue.scheduleBroadcastsLocked();
18105            }
18106            registeredReceivers = null;
18107            NR = 0;
18108        }
18109
18110        // Merge into one list.
18111        int ir = 0;
18112        if (receivers != null) {
18113            // A special case for PACKAGE_ADDED: do not allow the package
18114            // being added to see this broadcast.  This prevents them from
18115            // using this as a back door to get run as soon as they are
18116            // installed.  Maybe in the future we want to have a special install
18117            // broadcast or such for apps, but we'd like to deliberately make
18118            // this decision.
18119            String skipPackages[] = null;
18120            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18121                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18122                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18123                Uri data = intent.getData();
18124                if (data != null) {
18125                    String pkgName = data.getSchemeSpecificPart();
18126                    if (pkgName != null) {
18127                        skipPackages = new String[] { pkgName };
18128                    }
18129                }
18130            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18131                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18132            }
18133            if (skipPackages != null && (skipPackages.length > 0)) {
18134                for (String skipPackage : skipPackages) {
18135                    if (skipPackage != null) {
18136                        int NT = receivers.size();
18137                        for (int it=0; it<NT; it++) {
18138                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18139                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18140                                receivers.remove(it);
18141                                it--;
18142                                NT--;
18143                            }
18144                        }
18145                    }
18146                }
18147            }
18148
18149            int NT = receivers != null ? receivers.size() : 0;
18150            int it = 0;
18151            ResolveInfo curt = null;
18152            BroadcastFilter curr = null;
18153            while (it < NT && ir < NR) {
18154                if (curt == null) {
18155                    curt = (ResolveInfo)receivers.get(it);
18156                }
18157                if (curr == null) {
18158                    curr = registeredReceivers.get(ir);
18159                }
18160                if (curr.getPriority() >= curt.priority) {
18161                    // Insert this broadcast record into the final list.
18162                    receivers.add(it, curr);
18163                    ir++;
18164                    curr = null;
18165                    it++;
18166                    NT++;
18167                } else {
18168                    // Skip to the next ResolveInfo in the final list.
18169                    it++;
18170                    curt = null;
18171                }
18172            }
18173        }
18174        while (ir < NR) {
18175            if (receivers == null) {
18176                receivers = new ArrayList();
18177            }
18178            receivers.add(registeredReceivers.get(ir));
18179            ir++;
18180        }
18181
18182        if ((receivers != null && receivers.size() > 0)
18183                || resultTo != null) {
18184            BroadcastQueue queue = broadcastQueueForIntent(intent);
18185            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18186                    callerPackage, callingPid, callingUid, resolvedType,
18187                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18188                    resultData, resultExtras, ordered, sticky, false, userId);
18189
18190            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18191                    + ": prev had " + queue.mOrderedBroadcasts.size());
18192            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18193                    "Enqueueing broadcast " + r.intent.getAction());
18194
18195            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18196            if (!replaced) {
18197                queue.enqueueOrderedBroadcastLocked(r);
18198                queue.scheduleBroadcastsLocked();
18199            }
18200        } else {
18201            // There was nobody interested in the broadcast, but we still want to record
18202            // that it happened.
18203            if (intent.getComponent() == null && intent.getPackage() == null
18204                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18205                // This was an implicit broadcast... let's record it for posterity.
18206                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18207            }
18208        }
18209
18210        return ActivityManager.BROADCAST_SUCCESS;
18211    }
18212
18213    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18214            int skipCount, long dispatchTime) {
18215        final long now = SystemClock.elapsedRealtime();
18216        if (mCurBroadcastStats == null ||
18217                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18218            mLastBroadcastStats = mCurBroadcastStats;
18219            if (mLastBroadcastStats != null) {
18220                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18221                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18222            }
18223            mCurBroadcastStats = new BroadcastStats();
18224        }
18225        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18226    }
18227
18228    final Intent verifyBroadcastLocked(Intent intent) {
18229        // Refuse possible leaked file descriptors
18230        if (intent != null && intent.hasFileDescriptors() == true) {
18231            throw new IllegalArgumentException("File descriptors passed in Intent");
18232        }
18233
18234        int flags = intent.getFlags();
18235
18236        if (!mProcessesReady) {
18237            // if the caller really truly claims to know what they're doing, go
18238            // ahead and allow the broadcast without launching any receivers
18239            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18240                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18241            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18242                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18243                        + " before boot completion");
18244                throw new IllegalStateException("Cannot broadcast before boot completed");
18245            }
18246        }
18247
18248        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18249            throw new IllegalArgumentException(
18250                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18251        }
18252
18253        return intent;
18254    }
18255
18256    public final int broadcastIntent(IApplicationThread caller,
18257            Intent intent, String resolvedType, IIntentReceiver resultTo,
18258            int resultCode, String resultData, Bundle resultExtras,
18259            String[] requiredPermissions, int appOp, Bundle bOptions,
18260            boolean serialized, boolean sticky, int userId) {
18261        enforceNotIsolatedCaller("broadcastIntent");
18262        synchronized(this) {
18263            intent = verifyBroadcastLocked(intent);
18264
18265            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18266            final int callingPid = Binder.getCallingPid();
18267            final int callingUid = Binder.getCallingUid();
18268            final long origId = Binder.clearCallingIdentity();
18269            int res = broadcastIntentLocked(callerApp,
18270                    callerApp != null ? callerApp.info.packageName : null,
18271                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18272                    requiredPermissions, appOp, bOptions, serialized, sticky,
18273                    callingPid, callingUid, userId);
18274            Binder.restoreCallingIdentity(origId);
18275            return res;
18276        }
18277    }
18278
18279
18280    int broadcastIntentInPackage(String packageName, int uid,
18281            Intent intent, String resolvedType, IIntentReceiver resultTo,
18282            int resultCode, String resultData, Bundle resultExtras,
18283            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18284            int userId) {
18285        synchronized(this) {
18286            intent = verifyBroadcastLocked(intent);
18287
18288            final long origId = Binder.clearCallingIdentity();
18289            String[] requiredPermissions = requiredPermission == null ? null
18290                    : new String[] {requiredPermission};
18291            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18292                    resultTo, resultCode, resultData, resultExtras,
18293                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18294                    sticky, -1, uid, userId);
18295            Binder.restoreCallingIdentity(origId);
18296            return res;
18297        }
18298    }
18299
18300    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18301        // Refuse possible leaked file descriptors
18302        if (intent != null && intent.hasFileDescriptors() == true) {
18303            throw new IllegalArgumentException("File descriptors passed in Intent");
18304        }
18305
18306        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18307                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18308
18309        synchronized(this) {
18310            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18311                    != PackageManager.PERMISSION_GRANTED) {
18312                String msg = "Permission Denial: unbroadcastIntent() from pid="
18313                        + Binder.getCallingPid()
18314                        + ", uid=" + Binder.getCallingUid()
18315                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18316                Slog.w(TAG, msg);
18317                throw new SecurityException(msg);
18318            }
18319            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18320            if (stickies != null) {
18321                ArrayList<Intent> list = stickies.get(intent.getAction());
18322                if (list != null) {
18323                    int N = list.size();
18324                    int i;
18325                    for (i=0; i<N; i++) {
18326                        if (intent.filterEquals(list.get(i))) {
18327                            list.remove(i);
18328                            break;
18329                        }
18330                    }
18331                    if (list.size() <= 0) {
18332                        stickies.remove(intent.getAction());
18333                    }
18334                }
18335                if (stickies.size() <= 0) {
18336                    mStickyBroadcasts.remove(userId);
18337                }
18338            }
18339        }
18340    }
18341
18342    void backgroundServicesFinishedLocked(int userId) {
18343        for (BroadcastQueue queue : mBroadcastQueues) {
18344            queue.backgroundServicesFinishedLocked(userId);
18345        }
18346    }
18347
18348    public void finishReceiver(IBinder who, int resultCode, String resultData,
18349            Bundle resultExtras, boolean resultAbort, int flags) {
18350        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18351
18352        // Refuse possible leaked file descriptors
18353        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18354            throw new IllegalArgumentException("File descriptors passed in Bundle");
18355        }
18356
18357        final long origId = Binder.clearCallingIdentity();
18358        try {
18359            boolean doNext = false;
18360            BroadcastRecord r;
18361
18362            synchronized(this) {
18363                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18364                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18365                r = queue.getMatchingOrderedReceiver(who);
18366                if (r != null) {
18367                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18368                        resultData, resultExtras, resultAbort, true);
18369                }
18370            }
18371
18372            if (doNext) {
18373                r.queue.processNextBroadcast(false);
18374            }
18375            trimApplications();
18376        } finally {
18377            Binder.restoreCallingIdentity(origId);
18378        }
18379    }
18380
18381    // =========================================================
18382    // INSTRUMENTATION
18383    // =========================================================
18384
18385    public boolean startInstrumentation(ComponentName className,
18386            String profileFile, int flags, Bundle arguments,
18387            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18388            int userId, String abiOverride) {
18389        enforceNotIsolatedCaller("startInstrumentation");
18390        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18391                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18392        // Refuse possible leaked file descriptors
18393        if (arguments != null && arguments.hasFileDescriptors()) {
18394            throw new IllegalArgumentException("File descriptors passed in Bundle");
18395        }
18396
18397        synchronized(this) {
18398            InstrumentationInfo ii = null;
18399            ApplicationInfo ai = null;
18400            try {
18401                ii = mContext.getPackageManager().getInstrumentationInfo(
18402                    className, STOCK_PM_FLAGS);
18403                ai = AppGlobals.getPackageManager().getApplicationInfo(
18404                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18405            } catch (PackageManager.NameNotFoundException e) {
18406            } catch (RemoteException e) {
18407            }
18408            if (ii == null) {
18409                reportStartInstrumentationFailureLocked(watcher, className,
18410                        "Unable to find instrumentation info for: " + className);
18411                return false;
18412            }
18413            if (ai == null) {
18414                reportStartInstrumentationFailureLocked(watcher, className,
18415                        "Unable to find instrumentation target package: " + ii.targetPackage);
18416                return false;
18417            }
18418            if (!ai.hasCode()) {
18419                reportStartInstrumentationFailureLocked(watcher, className,
18420                        "Instrumentation target has no code: " + ii.targetPackage);
18421                return false;
18422            }
18423
18424            int match = mContext.getPackageManager().checkSignatures(
18425                    ii.targetPackage, ii.packageName);
18426            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18427                String msg = "Permission Denial: starting instrumentation "
18428                        + className + " from pid="
18429                        + Binder.getCallingPid()
18430                        + ", uid=" + Binder.getCallingPid()
18431                        + " not allowed because package " + ii.packageName
18432                        + " does not have a signature matching the target "
18433                        + ii.targetPackage;
18434                reportStartInstrumentationFailureLocked(watcher, className, msg);
18435                throw new SecurityException(msg);
18436            }
18437
18438            final long origId = Binder.clearCallingIdentity();
18439            // Instrumentation can kill and relaunch even persistent processes
18440            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18441                    "start instr");
18442            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18443            app.instrumentationClass = className;
18444            app.instrumentationInfo = ai;
18445            app.instrumentationProfileFile = profileFile;
18446            app.instrumentationArguments = arguments;
18447            app.instrumentationWatcher = watcher;
18448            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18449            app.instrumentationResultClass = className;
18450            Binder.restoreCallingIdentity(origId);
18451        }
18452
18453        return true;
18454    }
18455
18456    /**
18457     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18458     * error to the logs, but if somebody is watching, send the report there too.  This enables
18459     * the "am" command to report errors with more information.
18460     *
18461     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18462     * @param cn The component name of the instrumentation.
18463     * @param report The error report.
18464     */
18465    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18466            ComponentName cn, String report) {
18467        Slog.w(TAG, report);
18468        if (watcher != null) {
18469            Bundle results = new Bundle();
18470            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18471            results.putString("Error", report);
18472            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18473        }
18474    }
18475
18476    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18477        if (app.instrumentationWatcher != null) {
18478            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18479                    app.instrumentationClass, resultCode, results);
18480        }
18481
18482        // Can't call out of the system process with a lock held, so post a message.
18483        if (app.instrumentationUiAutomationConnection != null) {
18484            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18485                    app.instrumentationUiAutomationConnection).sendToTarget();
18486        }
18487
18488        app.instrumentationWatcher = null;
18489        app.instrumentationUiAutomationConnection = null;
18490        app.instrumentationClass = null;
18491        app.instrumentationInfo = null;
18492        app.instrumentationProfileFile = null;
18493        app.instrumentationArguments = null;
18494
18495        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18496                "finished inst");
18497    }
18498
18499    public void finishInstrumentation(IApplicationThread target,
18500            int resultCode, Bundle results) {
18501        int userId = UserHandle.getCallingUserId();
18502        // Refuse possible leaked file descriptors
18503        if (results != null && results.hasFileDescriptors()) {
18504            throw new IllegalArgumentException("File descriptors passed in Intent");
18505        }
18506
18507        synchronized(this) {
18508            ProcessRecord app = getRecordForAppLocked(target);
18509            if (app == null) {
18510                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18511                return;
18512            }
18513            final long origId = Binder.clearCallingIdentity();
18514            finishInstrumentationLocked(app, resultCode, results);
18515            Binder.restoreCallingIdentity(origId);
18516        }
18517    }
18518
18519    // =========================================================
18520    // CONFIGURATION
18521    // =========================================================
18522
18523    public ConfigurationInfo getDeviceConfigurationInfo() {
18524        ConfigurationInfo config = new ConfigurationInfo();
18525        synchronized (this) {
18526            config.reqTouchScreen = mConfiguration.touchscreen;
18527            config.reqKeyboardType = mConfiguration.keyboard;
18528            config.reqNavigation = mConfiguration.navigation;
18529            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18530                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18531                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18532            }
18533            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18534                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18535                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18536            }
18537            config.reqGlEsVersion = GL_ES_VERSION;
18538        }
18539        return config;
18540    }
18541
18542    ActivityStack getFocusedStack() {
18543        return mStackSupervisor.getFocusedStack();
18544    }
18545
18546    @Override
18547    public int getFocusedStackId() throws RemoteException {
18548        ActivityStack focusedStack = getFocusedStack();
18549        if (focusedStack != null) {
18550            return focusedStack.getStackId();
18551        }
18552        return -1;
18553    }
18554
18555    public Configuration getConfiguration() {
18556        Configuration ci;
18557        synchronized(this) {
18558            ci = new Configuration(mConfiguration);
18559            ci.userSetLocale = false;
18560        }
18561        return ci;
18562    }
18563
18564    @Override
18565    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18566        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18567        synchronized (this) {
18568            mSuppressResizeConfigChanges = suppress;
18569        }
18570    }
18571
18572    @Override
18573    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18574        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18575        if (fromStackId == HOME_STACK_ID) {
18576            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18577        }
18578        synchronized (this) {
18579            final long origId = Binder.clearCallingIdentity();
18580            try {
18581                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18582            } finally {
18583                Binder.restoreCallingIdentity(origId);
18584            }
18585        }
18586    }
18587
18588    @Override
18589    public void updatePersistentConfiguration(Configuration values) {
18590        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18591                "updateConfiguration()");
18592        enforceWriteSettingsPermission("updateConfiguration()");
18593        if (values == null) {
18594            throw new NullPointerException("Configuration must not be null");
18595        }
18596
18597        int userId = UserHandle.getCallingUserId();
18598
18599        synchronized(this) {
18600            final long origId = Binder.clearCallingIdentity();
18601            updateConfigurationLocked(values, null, false, true, userId);
18602            Binder.restoreCallingIdentity(origId);
18603        }
18604    }
18605
18606    private void updateFontScaleIfNeeded() {
18607        final int currentUserId;
18608        synchronized(this) {
18609            currentUserId = mUserController.getCurrentUserIdLocked();
18610        }
18611        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18612                FONT_SCALE, 1.0f, currentUserId);
18613        if (mConfiguration.fontScale != scaleFactor) {
18614            final Configuration configuration = mWindowManager.computeNewConfiguration();
18615            configuration.fontScale = scaleFactor;
18616            updatePersistentConfiguration(configuration);
18617        }
18618    }
18619
18620    private void enforceWriteSettingsPermission(String func) {
18621        int uid = Binder.getCallingUid();
18622        if (uid == Process.ROOT_UID) {
18623            return;
18624        }
18625
18626        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18627                Settings.getPackageNameForUid(mContext, uid), false)) {
18628            return;
18629        }
18630
18631        String msg = "Permission Denial: " + func + " from pid="
18632                + Binder.getCallingPid()
18633                + ", uid=" + uid
18634                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18635        Slog.w(TAG, msg);
18636        throw new SecurityException(msg);
18637    }
18638
18639    public void updateConfiguration(Configuration values) {
18640        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18641                "updateConfiguration()");
18642
18643        synchronized(this) {
18644            if (values == null && mWindowManager != null) {
18645                // sentinel: fetch the current configuration from the window manager
18646                values = mWindowManager.computeNewConfiguration();
18647            }
18648
18649            if (mWindowManager != null) {
18650                mProcessList.applyDisplaySize(mWindowManager);
18651            }
18652
18653            final long origId = Binder.clearCallingIdentity();
18654            if (values != null) {
18655                Settings.System.clearConfiguration(values);
18656            }
18657            updateConfigurationLocked(values, null, false);
18658            Binder.restoreCallingIdentity(origId);
18659        }
18660    }
18661
18662    void updateUserConfigurationLocked() {
18663        Configuration configuration = new Configuration(mConfiguration);
18664        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18665                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18666        updateConfigurationLocked(configuration, null, false);
18667    }
18668
18669    boolean updateConfigurationLocked(Configuration values,
18670            ActivityRecord starting, boolean initLocale) {
18671        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18672        return updateConfigurationLocked(values, starting, initLocale, false,
18673                UserHandle.USER_NULL);
18674    }
18675
18676    // To cache the list of supported system locales
18677    private String[] mSupportedSystemLocales = null;
18678
18679    /**
18680     * Do either or both things: (1) change the current configuration, and (2)
18681     * make sure the given activity is running with the (now) current
18682     * configuration.  Returns true if the activity has been left running, or
18683     * false if <var>starting</var> is being destroyed to match the new
18684     * configuration.
18685     *
18686     * @param userId is only used when persistent parameter is set to true to persist configuration
18687     *               for that particular user
18688     */
18689    private boolean updateConfigurationLocked(Configuration values,
18690            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18691        int changes = 0;
18692
18693        if (mWindowManager != null) {
18694            mWindowManager.deferSurfaceLayout();
18695        }
18696        if (values != null) {
18697            Configuration newConfig = new Configuration(mConfiguration);
18698            changes = newConfig.updateFrom(values);
18699            if (changes != 0) {
18700                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18701                        "Updating configuration to: " + values);
18702
18703                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18704
18705                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18706                    final LocaleList locales = values.getLocales();
18707                    int bestLocaleIndex = 0;
18708                    if (locales.size() > 1) {
18709                        if (mSupportedSystemLocales == null) {
18710                            mSupportedSystemLocales =
18711                                    Resources.getSystem().getAssets().getLocales();
18712                        }
18713                        bestLocaleIndex = Math.max(0,
18714                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18715                    }
18716                    SystemProperties.set("persist.sys.locale",
18717                            locales.get(bestLocaleIndex).toLanguageTag());
18718                    LocaleList.setDefault(locales, bestLocaleIndex);
18719                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18720                            locales.get(bestLocaleIndex)));
18721                }
18722
18723                mConfigurationSeq++;
18724                if (mConfigurationSeq <= 0) {
18725                    mConfigurationSeq = 1;
18726                }
18727                newConfig.seq = mConfigurationSeq;
18728                mConfiguration = newConfig;
18729                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18730                mUsageStatsService.reportConfigurationChange(newConfig,
18731                        mUserController.getCurrentUserIdLocked());
18732                //mUsageStatsService.noteStartConfig(newConfig);
18733
18734                final Configuration configCopy = new Configuration(mConfiguration);
18735
18736                // TODO: If our config changes, should we auto dismiss any currently
18737                // showing dialogs?
18738                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18739
18740                AttributeCache ac = AttributeCache.instance();
18741                if (ac != null) {
18742                    ac.updateConfiguration(configCopy);
18743                }
18744
18745                // Make sure all resources in our process are updated
18746                // right now, so that anyone who is going to retrieve
18747                // resource values after we return will be sure to get
18748                // the new ones.  This is especially important during
18749                // boot, where the first config change needs to guarantee
18750                // all resources have that config before following boot
18751                // code is executed.
18752                mSystemThread.applyConfigurationToResources(configCopy);
18753
18754                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18755                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18756                    msg.obj = new Configuration(configCopy);
18757                    msg.arg1 = userId;
18758                    mHandler.sendMessage(msg);
18759                }
18760
18761                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18762                if (isDensityChange) {
18763                    // Reset the unsupported display size dialog.
18764                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18765
18766                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18767                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18768                }
18769
18770                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18771                    ProcessRecord app = mLruProcesses.get(i);
18772                    try {
18773                        if (app.thread != null) {
18774                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18775                                    + app.processName + " new config " + mConfiguration);
18776                            app.thread.scheduleConfigurationChanged(configCopy);
18777                        }
18778                    } catch (Exception e) {
18779                    }
18780                }
18781                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18782                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18783                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18784                        | Intent.FLAG_RECEIVER_FOREGROUND);
18785                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18786                        null, AppOpsManager.OP_NONE, null, false, false,
18787                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18788                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18789                    // Tell the shortcut manager that the system locale changed.  It needs to know
18790                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18791                    // we "push" from here, rather than having the service listen to the broadcast.
18792                    final ShortcutServiceInternal shortcutService =
18793                            LocalServices.getService(ShortcutServiceInternal.class);
18794                    if (shortcutService != null) {
18795                        shortcutService.onSystemLocaleChangedNoLock();
18796                    }
18797
18798                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18799                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18800                    if (!mProcessesReady) {
18801                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18802                    }
18803                    broadcastIntentLocked(null, null, intent,
18804                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18805                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18806                }
18807            }
18808            // Update the configuration with WM first and check if any of the stacks need to be
18809            // resized due to the configuration change. If so, resize the stacks now and do any
18810            // relaunches if necessary. This way we don't need to relaunch again below in
18811            // ensureActivityConfigurationLocked().
18812            if (mWindowManager != null) {
18813                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18814                if (resizedStacks != null) {
18815                    for (int stackId : resizedStacks) {
18816                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18817                        mStackSupervisor.resizeStackLocked(
18818                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18819                    }
18820                }
18821            }
18822        }
18823
18824        boolean kept = true;
18825        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18826        // mainStack is null during startup.
18827        if (mainStack != null) {
18828            if (changes != 0 && starting == null) {
18829                // If the configuration changed, and the caller is not already
18830                // in the process of starting an activity, then find the top
18831                // activity to check if its configuration needs to change.
18832                starting = mainStack.topRunningActivityLocked();
18833            }
18834
18835            if (starting != null) {
18836                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18837                // And we need to make sure at this point that all other activities
18838                // are made visible with the correct configuration.
18839                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18840                        !PRESERVE_WINDOWS);
18841            }
18842        }
18843        if (mWindowManager != null) {
18844            mWindowManager.continueSurfaceLayout();
18845        }
18846        return kept;
18847    }
18848
18849    /**
18850     * Decide based on the configuration whether we should shouw the ANR,
18851     * crash, etc dialogs.  The idea is that if there is no affordnace to
18852     * press the on-screen buttons, we shouldn't show the dialog.
18853     *
18854     * A thought: SystemUI might also want to get told about this, the Power
18855     * dialog / global actions also might want different behaviors.
18856     */
18857    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18858        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18859                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18860                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18861        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18862                                    == Configuration.UI_MODE_TYPE_CAR);
18863        return inputMethodExists && uiIsNotCarType && !inVrMode;
18864    }
18865
18866    @Override
18867    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18868        synchronized (this) {
18869            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18870            if (srec != null) {
18871                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18872            }
18873        }
18874        return false;
18875    }
18876
18877    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18878            Intent resultData) {
18879
18880        synchronized (this) {
18881            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18882            if (r != null) {
18883                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18884            }
18885            return false;
18886        }
18887    }
18888
18889    public int getLaunchedFromUid(IBinder activityToken) {
18890        ActivityRecord srec;
18891        synchronized (this) {
18892            srec = ActivityRecord.forTokenLocked(activityToken);
18893        }
18894        if (srec == null) {
18895            return -1;
18896        }
18897        return srec.launchedFromUid;
18898    }
18899
18900    public String getLaunchedFromPackage(IBinder activityToken) {
18901        ActivityRecord srec;
18902        synchronized (this) {
18903            srec = ActivityRecord.forTokenLocked(activityToken);
18904        }
18905        if (srec == null) {
18906            return null;
18907        }
18908        return srec.launchedFromPackage;
18909    }
18910
18911    // =========================================================
18912    // LIFETIME MANAGEMENT
18913    // =========================================================
18914
18915    // Returns which broadcast queue the app is the current [or imminent] receiver
18916    // on, or 'null' if the app is not an active broadcast recipient.
18917    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18918        BroadcastRecord r = app.curReceiver;
18919        if (r != null) {
18920            return r.queue;
18921        }
18922
18923        // It's not the current receiver, but it might be starting up to become one
18924        synchronized (this) {
18925            for (BroadcastQueue queue : mBroadcastQueues) {
18926                r = queue.mPendingBroadcast;
18927                if (r != null && r.curApp == app) {
18928                    // found it; report which queue it's in
18929                    return queue;
18930                }
18931            }
18932        }
18933
18934        return null;
18935    }
18936
18937    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18938            int targetUid, ComponentName targetComponent, String targetProcess) {
18939        if (!mTrackingAssociations) {
18940            return null;
18941        }
18942        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18943                = mAssociations.get(targetUid);
18944        if (components == null) {
18945            components = new ArrayMap<>();
18946            mAssociations.put(targetUid, components);
18947        }
18948        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18949        if (sourceUids == null) {
18950            sourceUids = new SparseArray<>();
18951            components.put(targetComponent, sourceUids);
18952        }
18953        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18954        if (sourceProcesses == null) {
18955            sourceProcesses = new ArrayMap<>();
18956            sourceUids.put(sourceUid, sourceProcesses);
18957        }
18958        Association ass = sourceProcesses.get(sourceProcess);
18959        if (ass == null) {
18960            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18961                    targetProcess);
18962            sourceProcesses.put(sourceProcess, ass);
18963        }
18964        ass.mCount++;
18965        ass.mNesting++;
18966        if (ass.mNesting == 1) {
18967            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18968            ass.mLastState = sourceState;
18969        }
18970        return ass;
18971    }
18972
18973    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18974            ComponentName targetComponent) {
18975        if (!mTrackingAssociations) {
18976            return;
18977        }
18978        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18979                = mAssociations.get(targetUid);
18980        if (components == null) {
18981            return;
18982        }
18983        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18984        if (sourceUids == null) {
18985            return;
18986        }
18987        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18988        if (sourceProcesses == null) {
18989            return;
18990        }
18991        Association ass = sourceProcesses.get(sourceProcess);
18992        if (ass == null || ass.mNesting <= 0) {
18993            return;
18994        }
18995        ass.mNesting--;
18996        if (ass.mNesting == 0) {
18997            long uptime = SystemClock.uptimeMillis();
18998            ass.mTime += uptime - ass.mStartTime;
18999            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19000                    += uptime - ass.mLastStateUptime;
19001            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19002        }
19003    }
19004
19005    private void noteUidProcessState(final int uid, final int state) {
19006        mBatteryStatsService.noteUidProcessState(uid, state);
19007        if (mTrackingAssociations) {
19008            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19009                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19010                        = mAssociations.valueAt(i1);
19011                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19012                    SparseArray<ArrayMap<String, Association>> sourceUids
19013                            = targetComponents.valueAt(i2);
19014                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19015                    if (sourceProcesses != null) {
19016                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19017                            Association ass = sourceProcesses.valueAt(i4);
19018                            if (ass.mNesting >= 1) {
19019                                // currently associated
19020                                long uptime = SystemClock.uptimeMillis();
19021                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19022                                        += uptime - ass.mLastStateUptime;
19023                                ass.mLastState = state;
19024                                ass.mLastStateUptime = uptime;
19025                            }
19026                        }
19027                    }
19028                }
19029            }
19030        }
19031    }
19032
19033    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19034            boolean doingAll, long now) {
19035        if (mAdjSeq == app.adjSeq) {
19036            // This adjustment has already been computed.
19037            return app.curRawAdj;
19038        }
19039
19040        if (app.thread == null) {
19041            app.adjSeq = mAdjSeq;
19042            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19043            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19044            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19045        }
19046
19047        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19048        app.adjSource = null;
19049        app.adjTarget = null;
19050        app.empty = false;
19051        app.cached = false;
19052
19053        final int activitiesSize = app.activities.size();
19054
19055        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19056            // The max adjustment doesn't allow this app to be anything
19057            // below foreground, so it is not worth doing work for it.
19058            app.adjType = "fixed";
19059            app.adjSeq = mAdjSeq;
19060            app.curRawAdj = app.maxAdj;
19061            app.foregroundActivities = false;
19062            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19063            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19064            // System processes can do UI, and when they do we want to have
19065            // them trim their memory after the user leaves the UI.  To
19066            // facilitate this, here we need to determine whether or not it
19067            // is currently showing UI.
19068            app.systemNoUi = true;
19069            if (app == TOP_APP) {
19070                app.systemNoUi = false;
19071                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19072                app.adjType = "pers-top-activity";
19073            } else if (activitiesSize > 0) {
19074                for (int j = 0; j < activitiesSize; j++) {
19075                    final ActivityRecord r = app.activities.get(j);
19076                    if (r.visible) {
19077                        app.systemNoUi = false;
19078                    }
19079                }
19080            }
19081            if (!app.systemNoUi) {
19082                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19083            }
19084            return (app.curAdj=app.maxAdj);
19085        }
19086
19087        app.systemNoUi = false;
19088
19089        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19090
19091        // Determine the importance of the process, starting with most
19092        // important to least, and assign an appropriate OOM adjustment.
19093        int adj;
19094        int schedGroup;
19095        int procState;
19096        boolean foregroundActivities = false;
19097        BroadcastQueue queue;
19098        if (app == TOP_APP) {
19099            // The last app on the list is the foreground app.
19100            adj = ProcessList.FOREGROUND_APP_ADJ;
19101            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19102            app.adjType = "top-activity";
19103            foregroundActivities = true;
19104            procState = PROCESS_STATE_CUR_TOP;
19105        } else if (app.instrumentationClass != null) {
19106            // Don't want to kill running instrumentation.
19107            adj = ProcessList.FOREGROUND_APP_ADJ;
19108            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19109            app.adjType = "instrumentation";
19110            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19111        } else if ((queue = isReceivingBroadcast(app)) != null) {
19112            // An app that is currently receiving a broadcast also
19113            // counts as being in the foreground for OOM killer purposes.
19114            // It's placed in a sched group based on the nature of the
19115            // broadcast as reflected by which queue it's active in.
19116            adj = ProcessList.FOREGROUND_APP_ADJ;
19117            schedGroup = (queue == mFgBroadcastQueue)
19118                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19119            app.adjType = "broadcast";
19120            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19121        } else if (app.executingServices.size() > 0) {
19122            // An app that is currently executing a service callback also
19123            // counts as being in the foreground.
19124            adj = ProcessList.FOREGROUND_APP_ADJ;
19125            schedGroup = app.execServicesFg ?
19126                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19127            app.adjType = "exec-service";
19128            procState = ActivityManager.PROCESS_STATE_SERVICE;
19129            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19130        } else {
19131            // As far as we know the process is empty.  We may change our mind later.
19132            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19133            // At this point we don't actually know the adjustment.  Use the cached adj
19134            // value that the caller wants us to.
19135            adj = cachedAdj;
19136            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19137            app.cached = true;
19138            app.empty = true;
19139            app.adjType = "cch-empty";
19140        }
19141
19142        // Examine all activities if not already foreground.
19143        if (!foregroundActivities && activitiesSize > 0) {
19144            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19145            for (int j = 0; j < activitiesSize; j++) {
19146                final ActivityRecord r = app.activities.get(j);
19147                if (r.app != app) {
19148                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19149                            + " instead of expected " + app);
19150                    if (r.app == null || (r.app.uid == app.uid)) {
19151                        // Only fix things up when they look sane
19152                        r.app = app;
19153                    } else {
19154                        continue;
19155                    }
19156                }
19157                if (r.visible) {
19158                    // App has a visible activity; only upgrade adjustment.
19159                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19160                        adj = ProcessList.VISIBLE_APP_ADJ;
19161                        app.adjType = "visible";
19162                    }
19163                    if (procState > PROCESS_STATE_CUR_TOP) {
19164                        procState = PROCESS_STATE_CUR_TOP;
19165                    }
19166                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19167                    app.cached = false;
19168                    app.empty = false;
19169                    foregroundActivities = true;
19170                    if (r.task != null && minLayer > 0) {
19171                        final int layer = r.task.mLayerRank;
19172                        if (layer >= 0 && minLayer > layer) {
19173                            minLayer = layer;
19174                        }
19175                    }
19176                    break;
19177                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19178                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19179                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19180                        app.adjType = "pausing";
19181                    }
19182                    if (procState > PROCESS_STATE_CUR_TOP) {
19183                        procState = PROCESS_STATE_CUR_TOP;
19184                    }
19185                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19186                    app.cached = false;
19187                    app.empty = false;
19188                    foregroundActivities = true;
19189                } else if (r.state == ActivityState.STOPPING) {
19190                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19191                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19192                        app.adjType = "stopping";
19193                    }
19194                    // For the process state, we will at this point consider the
19195                    // process to be cached.  It will be cached either as an activity
19196                    // or empty depending on whether the activity is finishing.  We do
19197                    // this so that we can treat the process as cached for purposes of
19198                    // memory trimming (determing current memory level, trim command to
19199                    // send to process) since there can be an arbitrary number of stopping
19200                    // processes and they should soon all go into the cached state.
19201                    if (!r.finishing) {
19202                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19203                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19204                        }
19205                    }
19206                    app.cached = false;
19207                    app.empty = false;
19208                    foregroundActivities = true;
19209                } else {
19210                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19211                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19212                        app.adjType = "cch-act";
19213                    }
19214                }
19215            }
19216            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19217                adj += minLayer;
19218            }
19219        }
19220
19221        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19222                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19223            if (app.foregroundServices) {
19224                // The user is aware of this app, so make it visible.
19225                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19226                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19227                app.cached = false;
19228                app.adjType = "fg-service";
19229                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19230            } else if (app.forcingToForeground != null) {
19231                // The user is aware of this app, so make it visible.
19232                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19233                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19234                app.cached = false;
19235                app.adjType = "force-fg";
19236                app.adjSource = app.forcingToForeground;
19237                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19238            }
19239        }
19240
19241        if (app == mHeavyWeightProcess) {
19242            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19243                // We don't want to kill the current heavy-weight process.
19244                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19245                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19246                app.cached = false;
19247                app.adjType = "heavy";
19248            }
19249            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19250                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19251            }
19252        }
19253
19254        if (app == mHomeProcess) {
19255            if (adj > ProcessList.HOME_APP_ADJ) {
19256                // This process is hosting what we currently consider to be the
19257                // home app, so we don't want to let it go into the background.
19258                adj = ProcessList.HOME_APP_ADJ;
19259                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19260                app.cached = false;
19261                app.adjType = "home";
19262            }
19263            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19264                procState = ActivityManager.PROCESS_STATE_HOME;
19265            }
19266        }
19267
19268        if (app == mPreviousProcess && app.activities.size() > 0) {
19269            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19270                // This was the previous process that showed UI to the user.
19271                // We want to try to keep it around more aggressively, to give
19272                // a good experience around switching between two apps.
19273                adj = ProcessList.PREVIOUS_APP_ADJ;
19274                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19275                app.cached = false;
19276                app.adjType = "previous";
19277            }
19278            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19279                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19280            }
19281        }
19282
19283        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19284                + " reason=" + app.adjType);
19285
19286        // By default, we use the computed adjustment.  It may be changed if
19287        // there are applications dependent on our services or providers, but
19288        // this gives us a baseline and makes sure we don't get into an
19289        // infinite recursion.
19290        app.adjSeq = mAdjSeq;
19291        app.curRawAdj = adj;
19292        app.hasStartedServices = false;
19293
19294        if (mBackupTarget != null && app == mBackupTarget.app) {
19295            // If possible we want to avoid killing apps while they're being backed up
19296            if (adj > ProcessList.BACKUP_APP_ADJ) {
19297                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19298                adj = ProcessList.BACKUP_APP_ADJ;
19299                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19300                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19301                }
19302                app.adjType = "backup";
19303                app.cached = false;
19304            }
19305            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19306                procState = ActivityManager.PROCESS_STATE_BACKUP;
19307            }
19308        }
19309
19310        boolean mayBeTop = false;
19311        app.whitelistManager = false;
19312
19313        for (int is = app.services.size()-1;
19314                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19315                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19316                        || procState > ActivityManager.PROCESS_STATE_TOP);
19317                is--) {
19318            ServiceRecord s = app.services.valueAt(is);
19319            if (s.startRequested) {
19320                app.hasStartedServices = true;
19321                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19322                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19323                }
19324                if (app.hasShownUi && app != mHomeProcess) {
19325                    // If this process has shown some UI, let it immediately
19326                    // go to the LRU list because it may be pretty heavy with
19327                    // UI stuff.  We'll tag it with a label just to help
19328                    // debug and understand what is going on.
19329                    if (adj > ProcessList.SERVICE_ADJ) {
19330                        app.adjType = "cch-started-ui-services";
19331                    }
19332                } else {
19333                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19334                        // This service has seen some activity within
19335                        // recent memory, so we will keep its process ahead
19336                        // of the background processes.
19337                        if (adj > ProcessList.SERVICE_ADJ) {
19338                            adj = ProcessList.SERVICE_ADJ;
19339                            app.adjType = "started-services";
19340                            app.cached = false;
19341                        }
19342                    }
19343                    // If we have let the service slide into the background
19344                    // state, still have some text describing what it is doing
19345                    // even though the service no longer has an impact.
19346                    if (adj > ProcessList.SERVICE_ADJ) {
19347                        app.adjType = "cch-started-services";
19348                    }
19349                }
19350            }
19351
19352            for (int conni = s.connections.size()-1;
19353                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19354                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19355                            || procState > ActivityManager.PROCESS_STATE_TOP);
19356                    conni--) {
19357                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19358                for (int i = 0;
19359                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19360                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19361                                || procState > ActivityManager.PROCESS_STATE_TOP);
19362                        i++) {
19363                    // XXX should compute this based on the max of
19364                    // all connected clients.
19365                    ConnectionRecord cr = clist.get(i);
19366                    if (cr.binding.client == app) {
19367                        // Binding to ourself is not interesting.
19368                        continue;
19369                    }
19370                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19371                        app.whitelistManager = true;
19372                    }
19373
19374                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19375                        ProcessRecord client = cr.binding.client;
19376                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19377                                TOP_APP, doingAll, now);
19378                        int clientProcState = client.curProcState;
19379                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19380                            // If the other app is cached for any reason, for purposes here
19381                            // we are going to consider it empty.  The specific cached state
19382                            // doesn't propagate except under certain conditions.
19383                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19384                        }
19385                        String adjType = null;
19386                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19387                            // Not doing bind OOM management, so treat
19388                            // this guy more like a started service.
19389                            if (app.hasShownUi && app != mHomeProcess) {
19390                                // If this process has shown some UI, let it immediately
19391                                // go to the LRU list because it may be pretty heavy with
19392                                // UI stuff.  We'll tag it with a label just to help
19393                                // debug and understand what is going on.
19394                                if (adj > clientAdj) {
19395                                    adjType = "cch-bound-ui-services";
19396                                }
19397                                app.cached = false;
19398                                clientAdj = adj;
19399                                clientProcState = procState;
19400                            } else {
19401                                if (now >= (s.lastActivity
19402                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19403                                    // This service has not seen activity within
19404                                    // recent memory, so allow it to drop to the
19405                                    // LRU list if there is no other reason to keep
19406                                    // it around.  We'll also tag it with a label just
19407                                    // to help debug and undertand what is going on.
19408                                    if (adj > clientAdj) {
19409                                        adjType = "cch-bound-services";
19410                                    }
19411                                    clientAdj = adj;
19412                                }
19413                            }
19414                        }
19415                        if (adj > clientAdj) {
19416                            // If this process has recently shown UI, and
19417                            // the process that is binding to it is less
19418                            // important than being visible, then we don't
19419                            // care about the binding as much as we care
19420                            // about letting this process get into the LRU
19421                            // list to be killed and restarted if needed for
19422                            // memory.
19423                            if (app.hasShownUi && app != mHomeProcess
19424                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19425                                adjType = "cch-bound-ui-services";
19426                            } else {
19427                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19428                                        |Context.BIND_IMPORTANT)) != 0) {
19429                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19430                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19431                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19432                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19433                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19434                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19435                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19436                                    adj = clientAdj;
19437                                } else {
19438                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19439                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19440                                    }
19441                                }
19442                                if (!client.cached) {
19443                                    app.cached = false;
19444                                }
19445                                adjType = "service";
19446                            }
19447                        }
19448                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19449                            // This will treat important bound services identically to
19450                            // the top app, which may behave differently than generic
19451                            // foreground work.
19452                            if (client.curSchedGroup > schedGroup) {
19453                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19454                                    schedGroup = client.curSchedGroup;
19455                                } else {
19456                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19457                                }
19458                            }
19459                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19460                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19461                                    // Special handling of clients who are in the top state.
19462                                    // We *may* want to consider this process to be in the
19463                                    // top state as well, but only if there is not another
19464                                    // reason for it to be running.  Being on the top is a
19465                                    // special state, meaning you are specifically running
19466                                    // for the current top app.  If the process is already
19467                                    // running in the background for some other reason, it
19468                                    // is more important to continue considering it to be
19469                                    // in the background state.
19470                                    mayBeTop = true;
19471                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19472                                } else {
19473                                    // Special handling for above-top states (persistent
19474                                    // processes).  These should not bring the current process
19475                                    // into the top state, since they are not on top.  Instead
19476                                    // give them the best state after that.
19477                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19478                                        clientProcState =
19479                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19480                                    } else if (mWakefulness
19481                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19482                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19483                                                    != 0) {
19484                                        clientProcState =
19485                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19486                                    } else {
19487                                        clientProcState =
19488                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19489                                    }
19490                                }
19491                            }
19492                        } else {
19493                            if (clientProcState <
19494                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19495                                clientProcState =
19496                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19497                            }
19498                        }
19499                        if (procState > clientProcState) {
19500                            procState = clientProcState;
19501                        }
19502                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19503                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19504                            app.pendingUiClean = true;
19505                        }
19506                        if (adjType != null) {
19507                            app.adjType = adjType;
19508                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19509                                    .REASON_SERVICE_IN_USE;
19510                            app.adjSource = cr.binding.client;
19511                            app.adjSourceProcState = clientProcState;
19512                            app.adjTarget = s.name;
19513                        }
19514                    }
19515                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19516                        app.treatLikeActivity = true;
19517                    }
19518                    final ActivityRecord a = cr.activity;
19519                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19520                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19521                            (a.visible || a.state == ActivityState.RESUMED ||
19522                             a.state == ActivityState.PAUSING)) {
19523                            adj = ProcessList.FOREGROUND_APP_ADJ;
19524                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19525                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19526                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19527                                } else {
19528                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19529                                }
19530                            }
19531                            app.cached = false;
19532                            app.adjType = "service";
19533                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19534                                    .REASON_SERVICE_IN_USE;
19535                            app.adjSource = a;
19536                            app.adjSourceProcState = procState;
19537                            app.adjTarget = s.name;
19538                        }
19539                    }
19540                }
19541            }
19542        }
19543
19544        for (int provi = app.pubProviders.size()-1;
19545                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19546                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19547                        || procState > ActivityManager.PROCESS_STATE_TOP);
19548                provi--) {
19549            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19550            for (int i = cpr.connections.size()-1;
19551                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19552                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19553                            || procState > ActivityManager.PROCESS_STATE_TOP);
19554                    i--) {
19555                ContentProviderConnection conn = cpr.connections.get(i);
19556                ProcessRecord client = conn.client;
19557                if (client == app) {
19558                    // Being our own client is not interesting.
19559                    continue;
19560                }
19561                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19562                int clientProcState = client.curProcState;
19563                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19564                    // If the other app is cached for any reason, for purposes here
19565                    // we are going to consider it empty.
19566                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19567                }
19568                if (adj > clientAdj) {
19569                    if (app.hasShownUi && app != mHomeProcess
19570                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19571                        app.adjType = "cch-ui-provider";
19572                    } else {
19573                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19574                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19575                        app.adjType = "provider";
19576                    }
19577                    app.cached &= client.cached;
19578                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19579                            .REASON_PROVIDER_IN_USE;
19580                    app.adjSource = client;
19581                    app.adjSourceProcState = clientProcState;
19582                    app.adjTarget = cpr.name;
19583                }
19584                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19585                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19586                        // Special handling of clients who are in the top state.
19587                        // We *may* want to consider this process to be in the
19588                        // top state as well, but only if there is not another
19589                        // reason for it to be running.  Being on the top is a
19590                        // special state, meaning you are specifically running
19591                        // for the current top app.  If the process is already
19592                        // running in the background for some other reason, it
19593                        // is more important to continue considering it to be
19594                        // in the background state.
19595                        mayBeTop = true;
19596                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19597                    } else {
19598                        // Special handling for above-top states (persistent
19599                        // processes).  These should not bring the current process
19600                        // into the top state, since they are not on top.  Instead
19601                        // give them the best state after that.
19602                        clientProcState =
19603                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19604                    }
19605                }
19606                if (procState > clientProcState) {
19607                    procState = clientProcState;
19608                }
19609                if (client.curSchedGroup > schedGroup) {
19610                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19611                }
19612            }
19613            // If the provider has external (non-framework) process
19614            // dependencies, ensure that its adjustment is at least
19615            // FOREGROUND_APP_ADJ.
19616            if (cpr.hasExternalProcessHandles()) {
19617                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19618                    adj = ProcessList.FOREGROUND_APP_ADJ;
19619                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19620                    app.cached = false;
19621                    app.adjType = "provider";
19622                    app.adjTarget = cpr.name;
19623                }
19624                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19625                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19626                }
19627            }
19628        }
19629
19630        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19631            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19632                adj = ProcessList.PREVIOUS_APP_ADJ;
19633                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19634                app.cached = false;
19635                app.adjType = "provider";
19636            }
19637            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19638                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19639            }
19640        }
19641
19642        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19643            // A client of one of our services or providers is in the top state.  We
19644            // *may* want to be in the top state, but not if we are already running in
19645            // the background for some other reason.  For the decision here, we are going
19646            // to pick out a few specific states that we want to remain in when a client
19647            // is top (states that tend to be longer-term) and otherwise allow it to go
19648            // to the top state.
19649            switch (procState) {
19650                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19651                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19652                case ActivityManager.PROCESS_STATE_SERVICE:
19653                    // These all are longer-term states, so pull them up to the top
19654                    // of the background states, but not all the way to the top state.
19655                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19656                    break;
19657                default:
19658                    // Otherwise, top is a better choice, so take it.
19659                    procState = ActivityManager.PROCESS_STATE_TOP;
19660                    break;
19661            }
19662        }
19663
19664        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19665            if (app.hasClientActivities) {
19666                // This is a cached process, but with client activities.  Mark it so.
19667                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19668                app.adjType = "cch-client-act";
19669            } else if (app.treatLikeActivity) {
19670                // This is a cached process, but somebody wants us to treat it like it has
19671                // an activity, okay!
19672                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19673                app.adjType = "cch-as-act";
19674            }
19675        }
19676
19677        if (adj == ProcessList.SERVICE_ADJ) {
19678            if (doingAll) {
19679                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19680                mNewNumServiceProcs++;
19681                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19682                if (!app.serviceb) {
19683                    // This service isn't far enough down on the LRU list to
19684                    // normally be a B service, but if we are low on RAM and it
19685                    // is large we want to force it down since we would prefer to
19686                    // keep launcher over it.
19687                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19688                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19689                        app.serviceHighRam = true;
19690                        app.serviceb = true;
19691                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19692                    } else {
19693                        mNewNumAServiceProcs++;
19694                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19695                    }
19696                } else {
19697                    app.serviceHighRam = false;
19698                }
19699            }
19700            if (app.serviceb) {
19701                adj = ProcessList.SERVICE_B_ADJ;
19702            }
19703        }
19704
19705        app.curRawAdj = adj;
19706
19707        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19708        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19709        if (adj > app.maxAdj) {
19710            adj = app.maxAdj;
19711            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19712                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19713            }
19714        }
19715
19716        // Do final modification to adj.  Everything we do between here and applying
19717        // the final setAdj must be done in this function, because we will also use
19718        // it when computing the final cached adj later.  Note that we don't need to
19719        // worry about this for max adj above, since max adj will always be used to
19720        // keep it out of the cached vaues.
19721        app.curAdj = app.modifyRawOomAdj(adj);
19722        app.curSchedGroup = schedGroup;
19723        app.curProcState = procState;
19724        app.foregroundActivities = foregroundActivities;
19725
19726        return app.curRawAdj;
19727    }
19728
19729    /**
19730     * Record new PSS sample for a process.
19731     */
19732    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19733            long now) {
19734        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19735                swapPss * 1024);
19736        proc.lastPssTime = now;
19737        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19738        if (DEBUG_PSS) Slog.d(TAG_PSS,
19739                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19740                + " state=" + ProcessList.makeProcStateString(procState));
19741        if (proc.initialIdlePss == 0) {
19742            proc.initialIdlePss = pss;
19743        }
19744        proc.lastPss = pss;
19745        proc.lastSwapPss = swapPss;
19746        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19747            proc.lastCachedPss = pss;
19748            proc.lastCachedSwapPss = swapPss;
19749        }
19750
19751        final SparseArray<Pair<Long, String>> watchUids
19752                = mMemWatchProcesses.getMap().get(proc.processName);
19753        Long check = null;
19754        if (watchUids != null) {
19755            Pair<Long, String> val = watchUids.get(proc.uid);
19756            if (val == null) {
19757                val = watchUids.get(0);
19758            }
19759            if (val != null) {
19760                check = val.first;
19761            }
19762        }
19763        if (check != null) {
19764            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19765                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19766                if (!isDebuggable) {
19767                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19768                        isDebuggable = true;
19769                    }
19770                }
19771                if (isDebuggable) {
19772                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19773                    final ProcessRecord myProc = proc;
19774                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19775                    mMemWatchDumpProcName = proc.processName;
19776                    mMemWatchDumpFile = heapdumpFile.toString();
19777                    mMemWatchDumpPid = proc.pid;
19778                    mMemWatchDumpUid = proc.uid;
19779                    BackgroundThread.getHandler().post(new Runnable() {
19780                        @Override
19781                        public void run() {
19782                            revokeUriPermission(ActivityThread.currentActivityThread()
19783                                            .getApplicationThread(),
19784                                    DumpHeapActivity.JAVA_URI,
19785                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19786                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19787                                    UserHandle.myUserId());
19788                            ParcelFileDescriptor fd = null;
19789                            try {
19790                                heapdumpFile.delete();
19791                                fd = ParcelFileDescriptor.open(heapdumpFile,
19792                                        ParcelFileDescriptor.MODE_CREATE |
19793                                                ParcelFileDescriptor.MODE_TRUNCATE |
19794                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19795                                                ParcelFileDescriptor.MODE_APPEND);
19796                                IApplicationThread thread = myProc.thread;
19797                                if (thread != null) {
19798                                    try {
19799                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19800                                                "Requesting dump heap from "
19801                                                + myProc + " to " + heapdumpFile);
19802                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19803                                    } catch (RemoteException e) {
19804                                    }
19805                                }
19806                            } catch (FileNotFoundException e) {
19807                                e.printStackTrace();
19808                            } finally {
19809                                if (fd != null) {
19810                                    try {
19811                                        fd.close();
19812                                    } catch (IOException e) {
19813                                    }
19814                                }
19815                            }
19816                        }
19817                    });
19818                } else {
19819                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19820                            + ", but debugging not enabled");
19821                }
19822            }
19823        }
19824    }
19825
19826    /**
19827     * Schedule PSS collection of a process.
19828     */
19829    void requestPssLocked(ProcessRecord proc, int procState) {
19830        if (mPendingPssProcesses.contains(proc)) {
19831            return;
19832        }
19833        if (mPendingPssProcesses.size() == 0) {
19834            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19835        }
19836        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19837        proc.pssProcState = procState;
19838        mPendingPssProcesses.add(proc);
19839    }
19840
19841    /**
19842     * Schedule PSS collection of all processes.
19843     */
19844    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19845        if (!always) {
19846            if (now < (mLastFullPssTime +
19847                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19848                return;
19849            }
19850        }
19851        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19852        mLastFullPssTime = now;
19853        mFullPssPending = true;
19854        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19855        mPendingPssProcesses.clear();
19856        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19857            ProcessRecord app = mLruProcesses.get(i);
19858            if (app.thread == null
19859                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19860                continue;
19861            }
19862            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19863                app.pssProcState = app.setProcState;
19864                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19865                        mTestPssMode, isSleepingLocked(), now);
19866                mPendingPssProcesses.add(app);
19867            }
19868        }
19869        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19870    }
19871
19872    public void setTestPssMode(boolean enabled) {
19873        synchronized (this) {
19874            mTestPssMode = enabled;
19875            if (enabled) {
19876                // Whenever we enable the mode, we want to take a snapshot all of current
19877                // process mem use.
19878                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19879            }
19880        }
19881    }
19882
19883    /**
19884     * Ask a given process to GC right now.
19885     */
19886    final void performAppGcLocked(ProcessRecord app) {
19887        try {
19888            app.lastRequestedGc = SystemClock.uptimeMillis();
19889            if (app.thread != null) {
19890                if (app.reportLowMemory) {
19891                    app.reportLowMemory = false;
19892                    app.thread.scheduleLowMemory();
19893                } else {
19894                    app.thread.processInBackground();
19895                }
19896            }
19897        } catch (Exception e) {
19898            // whatever.
19899        }
19900    }
19901
19902    /**
19903     * Returns true if things are idle enough to perform GCs.
19904     */
19905    private final boolean canGcNowLocked() {
19906        boolean processingBroadcasts = false;
19907        for (BroadcastQueue q : mBroadcastQueues) {
19908            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19909                processingBroadcasts = true;
19910            }
19911        }
19912        return !processingBroadcasts
19913                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19914    }
19915
19916    /**
19917     * Perform GCs on all processes that are waiting for it, but only
19918     * if things are idle.
19919     */
19920    final void performAppGcsLocked() {
19921        final int N = mProcessesToGc.size();
19922        if (N <= 0) {
19923            return;
19924        }
19925        if (canGcNowLocked()) {
19926            while (mProcessesToGc.size() > 0) {
19927                ProcessRecord proc = mProcessesToGc.remove(0);
19928                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19929                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19930                            <= SystemClock.uptimeMillis()) {
19931                        // To avoid spamming the system, we will GC processes one
19932                        // at a time, waiting a few seconds between each.
19933                        performAppGcLocked(proc);
19934                        scheduleAppGcsLocked();
19935                        return;
19936                    } else {
19937                        // It hasn't been long enough since we last GCed this
19938                        // process...  put it in the list to wait for its time.
19939                        addProcessToGcListLocked(proc);
19940                        break;
19941                    }
19942                }
19943            }
19944
19945            scheduleAppGcsLocked();
19946        }
19947    }
19948
19949    /**
19950     * If all looks good, perform GCs on all processes waiting for them.
19951     */
19952    final void performAppGcsIfAppropriateLocked() {
19953        if (canGcNowLocked()) {
19954            performAppGcsLocked();
19955            return;
19956        }
19957        // Still not idle, wait some more.
19958        scheduleAppGcsLocked();
19959    }
19960
19961    /**
19962     * Schedule the execution of all pending app GCs.
19963     */
19964    final void scheduleAppGcsLocked() {
19965        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19966
19967        if (mProcessesToGc.size() > 0) {
19968            // Schedule a GC for the time to the next process.
19969            ProcessRecord proc = mProcessesToGc.get(0);
19970            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19971
19972            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19973            long now = SystemClock.uptimeMillis();
19974            if (when < (now+GC_TIMEOUT)) {
19975                when = now + GC_TIMEOUT;
19976            }
19977            mHandler.sendMessageAtTime(msg, when);
19978        }
19979    }
19980
19981    /**
19982     * Add a process to the array of processes waiting to be GCed.  Keeps the
19983     * list in sorted order by the last GC time.  The process can't already be
19984     * on the list.
19985     */
19986    final void addProcessToGcListLocked(ProcessRecord proc) {
19987        boolean added = false;
19988        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19989            if (mProcessesToGc.get(i).lastRequestedGc <
19990                    proc.lastRequestedGc) {
19991                added = true;
19992                mProcessesToGc.add(i+1, proc);
19993                break;
19994            }
19995        }
19996        if (!added) {
19997            mProcessesToGc.add(0, proc);
19998        }
19999    }
20000
20001    /**
20002     * Set up to ask a process to GC itself.  This will either do it
20003     * immediately, or put it on the list of processes to gc the next
20004     * time things are idle.
20005     */
20006    final void scheduleAppGcLocked(ProcessRecord app) {
20007        long now = SystemClock.uptimeMillis();
20008        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20009            return;
20010        }
20011        if (!mProcessesToGc.contains(app)) {
20012            addProcessToGcListLocked(app);
20013            scheduleAppGcsLocked();
20014        }
20015    }
20016
20017    final void checkExcessivePowerUsageLocked(boolean doKills) {
20018        updateCpuStatsNow();
20019
20020        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20021        boolean doWakeKills = doKills;
20022        boolean doCpuKills = doKills;
20023        if (mLastPowerCheckRealtime == 0) {
20024            doWakeKills = false;
20025        }
20026        if (mLastPowerCheckUptime == 0) {
20027            doCpuKills = false;
20028        }
20029        if (stats.isScreenOn()) {
20030            doWakeKills = false;
20031        }
20032        final long curRealtime = SystemClock.elapsedRealtime();
20033        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20034        final long curUptime = SystemClock.uptimeMillis();
20035        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20036        mLastPowerCheckRealtime = curRealtime;
20037        mLastPowerCheckUptime = curUptime;
20038        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20039            doWakeKills = false;
20040        }
20041        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20042            doCpuKills = false;
20043        }
20044        int i = mLruProcesses.size();
20045        while (i > 0) {
20046            i--;
20047            ProcessRecord app = mLruProcesses.get(i);
20048            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20049                long wtime;
20050                synchronized (stats) {
20051                    wtime = stats.getProcessWakeTime(app.info.uid,
20052                            app.pid, curRealtime);
20053                }
20054                long wtimeUsed = wtime - app.lastWakeTime;
20055                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20056                if (DEBUG_POWER) {
20057                    StringBuilder sb = new StringBuilder(128);
20058                    sb.append("Wake for ");
20059                    app.toShortString(sb);
20060                    sb.append(": over ");
20061                    TimeUtils.formatDuration(realtimeSince, sb);
20062                    sb.append(" used ");
20063                    TimeUtils.formatDuration(wtimeUsed, sb);
20064                    sb.append(" (");
20065                    sb.append((wtimeUsed*100)/realtimeSince);
20066                    sb.append("%)");
20067                    Slog.i(TAG_POWER, sb.toString());
20068                    sb.setLength(0);
20069                    sb.append("CPU for ");
20070                    app.toShortString(sb);
20071                    sb.append(": over ");
20072                    TimeUtils.formatDuration(uptimeSince, sb);
20073                    sb.append(" used ");
20074                    TimeUtils.formatDuration(cputimeUsed, sb);
20075                    sb.append(" (");
20076                    sb.append((cputimeUsed*100)/uptimeSince);
20077                    sb.append("%)");
20078                    Slog.i(TAG_POWER, sb.toString());
20079                }
20080                // If a process has held a wake lock for more
20081                // than 50% of the time during this period,
20082                // that sounds bad.  Kill!
20083                if (doWakeKills && realtimeSince > 0
20084                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20085                    synchronized (stats) {
20086                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20087                                realtimeSince, wtimeUsed);
20088                    }
20089                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20090                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20091                } else if (doCpuKills && uptimeSince > 0
20092                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20093                    synchronized (stats) {
20094                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20095                                uptimeSince, cputimeUsed);
20096                    }
20097                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20098                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20099                } else {
20100                    app.lastWakeTime = wtime;
20101                    app.lastCpuTime = app.curCpuTime;
20102                }
20103            }
20104        }
20105    }
20106
20107    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20108            long nowElapsed) {
20109        boolean success = true;
20110
20111        if (app.curRawAdj != app.setRawAdj) {
20112            app.setRawAdj = app.curRawAdj;
20113        }
20114
20115        int changes = 0;
20116
20117        if (app.curAdj != app.setAdj) {
20118            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20119            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20120                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20121                    + app.adjType);
20122            app.setAdj = app.curAdj;
20123            app.verifiedAdj = ProcessList.INVALID_ADJ;
20124        }
20125
20126        if (app.setSchedGroup != app.curSchedGroup) {
20127            app.setSchedGroup = app.curSchedGroup;
20128            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20129                    "Setting sched group of " + app.processName
20130                    + " to " + app.curSchedGroup);
20131            if (app.waitingToKill != null && app.curReceiver == null
20132                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20133                app.kill(app.waitingToKill, true);
20134                success = false;
20135            } else {
20136                int processGroup;
20137                switch (app.curSchedGroup) {
20138                    case ProcessList.SCHED_GROUP_BACKGROUND:
20139                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20140                        break;
20141                    case ProcessList.SCHED_GROUP_TOP_APP:
20142                        processGroup = Process.THREAD_GROUP_TOP_APP;
20143                        break;
20144                    default:
20145                        processGroup = Process.THREAD_GROUP_DEFAULT;
20146                        break;
20147                }
20148                if (true) {
20149                    long oldId = Binder.clearCallingIdentity();
20150                    try {
20151                        Process.setProcessGroup(app.pid, processGroup);
20152                    } catch (Exception e) {
20153                        Slog.w(TAG, "Failed setting process group of " + app.pid
20154                                + " to " + app.curSchedGroup);
20155                        e.printStackTrace();
20156                    } finally {
20157                        Binder.restoreCallingIdentity(oldId);
20158                    }
20159                } else {
20160                    if (app.thread != null) {
20161                        try {
20162                            app.thread.setSchedulingGroup(processGroup);
20163                        } catch (RemoteException e) {
20164                        }
20165                    }
20166                }
20167            }
20168        }
20169        if (app.repForegroundActivities != app.foregroundActivities) {
20170            app.repForegroundActivities = app.foregroundActivities;
20171            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20172        }
20173        if (app.repProcState != app.curProcState) {
20174            app.repProcState = app.curProcState;
20175            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20176            if (app.thread != null) {
20177                try {
20178                    if (false) {
20179                        //RuntimeException h = new RuntimeException("here");
20180                        Slog.i(TAG, "Sending new process state " + app.repProcState
20181                                + " to " + app /*, h*/);
20182                    }
20183                    app.thread.setProcessState(app.repProcState);
20184                } catch (RemoteException e) {
20185                }
20186            }
20187        }
20188        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20189                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20190            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20191                // Experimental code to more aggressively collect pss while
20192                // running test...  the problem is that this tends to collect
20193                // the data right when a process is transitioning between process
20194                // states, which well tend to give noisy data.
20195                long start = SystemClock.uptimeMillis();
20196                long pss = Debug.getPss(app.pid, mTmpLong, null);
20197                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20198                mPendingPssProcesses.remove(app);
20199                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20200                        + " to " + app.curProcState + ": "
20201                        + (SystemClock.uptimeMillis()-start) + "ms");
20202            }
20203            app.lastStateTime = now;
20204            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20205                    mTestPssMode, isSleepingLocked(), now);
20206            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20207                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20208                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20209                    + (app.nextPssTime-now) + ": " + app);
20210        } else {
20211            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20212                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20213                    mTestPssMode)))) {
20214                requestPssLocked(app, app.setProcState);
20215                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20216                        mTestPssMode, isSleepingLocked(), now);
20217            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20218                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20219        }
20220        if (app.setProcState != app.curProcState) {
20221            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20222                    "Proc state change of " + app.processName
20223                            + " to " + app.curProcState);
20224            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20225            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20226            if (setImportant && !curImportant) {
20227                // This app is no longer something we consider important enough to allow to
20228                // use arbitrary amounts of battery power.  Note
20229                // its current wake lock time to later know to kill it if
20230                // it is not behaving well.
20231                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20232                synchronized (stats) {
20233                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20234                            app.pid, nowElapsed);
20235                }
20236                app.lastCpuTime = app.curCpuTime;
20237
20238            }
20239            // Inform UsageStats of important process state change
20240            // Must be called before updating setProcState
20241            maybeUpdateUsageStatsLocked(app, nowElapsed);
20242
20243            app.setProcState = app.curProcState;
20244            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20245                app.notCachedSinceIdle = false;
20246            }
20247            if (!doingAll) {
20248                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20249            } else {
20250                app.procStateChanged = true;
20251            }
20252        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20253                > USAGE_STATS_INTERACTION_INTERVAL) {
20254            // For apps that sit around for a long time in the interactive state, we need
20255            // to report this at least once a day so they don't go idle.
20256            maybeUpdateUsageStatsLocked(app, nowElapsed);
20257        }
20258
20259        if (changes != 0) {
20260            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20261                    "Changes in " + app + ": " + changes);
20262            int i = mPendingProcessChanges.size()-1;
20263            ProcessChangeItem item = null;
20264            while (i >= 0) {
20265                item = mPendingProcessChanges.get(i);
20266                if (item.pid == app.pid) {
20267                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20268                            "Re-using existing item: " + item);
20269                    break;
20270                }
20271                i--;
20272            }
20273            if (i < 0) {
20274                // No existing item in pending changes; need a new one.
20275                final int NA = mAvailProcessChanges.size();
20276                if (NA > 0) {
20277                    item = mAvailProcessChanges.remove(NA-1);
20278                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20279                            "Retrieving available item: " + item);
20280                } else {
20281                    item = new ProcessChangeItem();
20282                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20283                            "Allocating new item: " + item);
20284                }
20285                item.changes = 0;
20286                item.pid = app.pid;
20287                item.uid = app.info.uid;
20288                if (mPendingProcessChanges.size() == 0) {
20289                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20290                            "*** Enqueueing dispatch processes changed!");
20291                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20292                }
20293                mPendingProcessChanges.add(item);
20294            }
20295            item.changes |= changes;
20296            item.processState = app.repProcState;
20297            item.foregroundActivities = app.repForegroundActivities;
20298            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20299                    "Item " + Integer.toHexString(System.identityHashCode(item))
20300                    + " " + app.toShortString() + ": changes=" + item.changes
20301                    + " procState=" + item.processState
20302                    + " foreground=" + item.foregroundActivities
20303                    + " type=" + app.adjType + " source=" + app.adjSource
20304                    + " target=" + app.adjTarget);
20305        }
20306
20307        return success;
20308    }
20309
20310    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20311        final UidRecord.ChangeItem pendingChange;
20312        if (uidRec == null || uidRec.pendingChange == null) {
20313            if (mPendingUidChanges.size() == 0) {
20314                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20315                        "*** Enqueueing dispatch uid changed!");
20316                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20317            }
20318            final int NA = mAvailUidChanges.size();
20319            if (NA > 0) {
20320                pendingChange = mAvailUidChanges.remove(NA-1);
20321                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20322                        "Retrieving available item: " + pendingChange);
20323            } else {
20324                pendingChange = new UidRecord.ChangeItem();
20325                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20326                        "Allocating new item: " + pendingChange);
20327            }
20328            if (uidRec != null) {
20329                uidRec.pendingChange = pendingChange;
20330                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20331                    // If this uid is going away, and we haven't yet reported it is gone,
20332                    // then do so now.
20333                    change = UidRecord.CHANGE_GONE_IDLE;
20334                }
20335            } else if (uid < 0) {
20336                throw new IllegalArgumentException("No UidRecord or uid");
20337            }
20338            pendingChange.uidRecord = uidRec;
20339            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20340            mPendingUidChanges.add(pendingChange);
20341        } else {
20342            pendingChange = uidRec.pendingChange;
20343            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20344                change = UidRecord.CHANGE_GONE_IDLE;
20345            }
20346        }
20347        pendingChange.change = change;
20348        pendingChange.processState = uidRec != null
20349                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20350    }
20351
20352    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20353            String authority) {
20354        if (app == null) return;
20355        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20356            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20357            if (userState == null) return;
20358            final long now = SystemClock.elapsedRealtime();
20359            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20360            if (lastReported == null || lastReported < now - 60 * 1000L) {
20361                mUsageStatsService.reportContentProviderUsage(
20362                        authority, providerPkgName, app.userId);
20363                userState.mProviderLastReportedFg.put(authority, now);
20364            }
20365        }
20366    }
20367
20368    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20369        if (DEBUG_USAGE_STATS) {
20370            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20371                    + "] state changes: old = " + app.setProcState + ", new = "
20372                    + app.curProcState);
20373        }
20374        if (mUsageStatsService == null) {
20375            return;
20376        }
20377        boolean isInteraction;
20378        // To avoid some abuse patterns, we are going to be careful about what we consider
20379        // to be an app interaction.  Being the top activity doesn't count while the display
20380        // is sleeping, nor do short foreground services.
20381        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20382            isInteraction = true;
20383            app.fgInteractionTime = 0;
20384        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20385            if (app.fgInteractionTime == 0) {
20386                app.fgInteractionTime = nowElapsed;
20387                isInteraction = false;
20388            } else {
20389                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20390            }
20391        } else {
20392            isInteraction = app.curProcState
20393                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20394            app.fgInteractionTime = 0;
20395        }
20396        if (isInteraction && (!app.reportedInteraction
20397                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20398            app.interactionEventTime = nowElapsed;
20399            String[] packages = app.getPackageList();
20400            if (packages != null) {
20401                for (int i = 0; i < packages.length; i++) {
20402                    mUsageStatsService.reportEvent(packages[i], app.userId,
20403                            UsageEvents.Event.SYSTEM_INTERACTION);
20404                }
20405            }
20406        }
20407        app.reportedInteraction = isInteraction;
20408        if (!isInteraction) {
20409            app.interactionEventTime = 0;
20410        }
20411    }
20412
20413    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20414        if (proc.thread != null) {
20415            if (proc.baseProcessTracker != null) {
20416                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20417            }
20418        }
20419    }
20420
20421    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20422            ProcessRecord TOP_APP, boolean doingAll, long now) {
20423        if (app.thread == null) {
20424            return false;
20425        }
20426
20427        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20428
20429        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20430    }
20431
20432    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20433            boolean oomAdj) {
20434        if (isForeground != proc.foregroundServices) {
20435            proc.foregroundServices = isForeground;
20436            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20437                    proc.info.uid);
20438            if (isForeground) {
20439                if (curProcs == null) {
20440                    curProcs = new ArrayList<ProcessRecord>();
20441                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20442                }
20443                if (!curProcs.contains(proc)) {
20444                    curProcs.add(proc);
20445                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20446                            proc.info.packageName, proc.info.uid);
20447                }
20448            } else {
20449                if (curProcs != null) {
20450                    if (curProcs.remove(proc)) {
20451                        mBatteryStatsService.noteEvent(
20452                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20453                                proc.info.packageName, proc.info.uid);
20454                        if (curProcs.size() <= 0) {
20455                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20456                        }
20457                    }
20458                }
20459            }
20460            if (oomAdj) {
20461                updateOomAdjLocked();
20462            }
20463        }
20464    }
20465
20466    private final ActivityRecord resumedAppLocked() {
20467        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20468        String pkg;
20469        int uid;
20470        if (act != null) {
20471            pkg = act.packageName;
20472            uid = act.info.applicationInfo.uid;
20473        } else {
20474            pkg = null;
20475            uid = -1;
20476        }
20477        // Has the UID or resumed package name changed?
20478        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20479                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20480            if (mCurResumedPackage != null) {
20481                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20482                        mCurResumedPackage, mCurResumedUid);
20483            }
20484            mCurResumedPackage = pkg;
20485            mCurResumedUid = uid;
20486            if (mCurResumedPackage != null) {
20487                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20488                        mCurResumedPackage, mCurResumedUid);
20489            }
20490        }
20491        return act;
20492    }
20493
20494    final boolean updateOomAdjLocked(ProcessRecord app) {
20495        final ActivityRecord TOP_ACT = resumedAppLocked();
20496        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20497        final boolean wasCached = app.cached;
20498
20499        mAdjSeq++;
20500
20501        // This is the desired cached adjusment we want to tell it to use.
20502        // If our app is currently cached, we know it, and that is it.  Otherwise,
20503        // we don't know it yet, and it needs to now be cached we will then
20504        // need to do a complete oom adj.
20505        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20506                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20507        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20508                SystemClock.uptimeMillis());
20509        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20510            // Changed to/from cached state, so apps after it in the LRU
20511            // list may also be changed.
20512            updateOomAdjLocked();
20513        }
20514        return success;
20515    }
20516
20517    final void updateOomAdjLocked() {
20518        final ActivityRecord TOP_ACT = resumedAppLocked();
20519        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20520        final long now = SystemClock.uptimeMillis();
20521        final long nowElapsed = SystemClock.elapsedRealtime();
20522        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20523        final int N = mLruProcesses.size();
20524
20525        if (false) {
20526            RuntimeException e = new RuntimeException();
20527            e.fillInStackTrace();
20528            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20529        }
20530
20531        // Reset state in all uid records.
20532        for (int i=mActiveUids.size()-1; i>=0; i--) {
20533            final UidRecord uidRec = mActiveUids.valueAt(i);
20534            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20535                    "Starting update of " + uidRec);
20536            uidRec.reset();
20537        }
20538
20539        mStackSupervisor.rankTaskLayersIfNeeded();
20540
20541        mAdjSeq++;
20542        mNewNumServiceProcs = 0;
20543        mNewNumAServiceProcs = 0;
20544
20545        final int emptyProcessLimit;
20546        final int cachedProcessLimit;
20547        if (mProcessLimit <= 0) {
20548            emptyProcessLimit = cachedProcessLimit = 0;
20549        } else if (mProcessLimit == 1) {
20550            emptyProcessLimit = 1;
20551            cachedProcessLimit = 0;
20552        } else {
20553            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20554            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20555        }
20556
20557        // Let's determine how many processes we have running vs.
20558        // how many slots we have for background processes; we may want
20559        // to put multiple processes in a slot of there are enough of
20560        // them.
20561        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20562                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20563        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20564        if (numEmptyProcs > cachedProcessLimit) {
20565            // If there are more empty processes than our limit on cached
20566            // processes, then use the cached process limit for the factor.
20567            // This ensures that the really old empty processes get pushed
20568            // down to the bottom, so if we are running low on memory we will
20569            // have a better chance at keeping around more cached processes
20570            // instead of a gazillion empty processes.
20571            numEmptyProcs = cachedProcessLimit;
20572        }
20573        int emptyFactor = numEmptyProcs/numSlots;
20574        if (emptyFactor < 1) emptyFactor = 1;
20575        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20576        if (cachedFactor < 1) cachedFactor = 1;
20577        int stepCached = 0;
20578        int stepEmpty = 0;
20579        int numCached = 0;
20580        int numEmpty = 0;
20581        int numTrimming = 0;
20582
20583        mNumNonCachedProcs = 0;
20584        mNumCachedHiddenProcs = 0;
20585
20586        // First update the OOM adjustment for each of the
20587        // application processes based on their current state.
20588        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20589        int nextCachedAdj = curCachedAdj+1;
20590        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20591        int nextEmptyAdj = curEmptyAdj+2;
20592        for (int i=N-1; i>=0; i--) {
20593            ProcessRecord app = mLruProcesses.get(i);
20594            if (!app.killedByAm && app.thread != null) {
20595                app.procStateChanged = false;
20596                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20597
20598                // If we haven't yet assigned the final cached adj
20599                // to the process, do that now.
20600                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20601                    switch (app.curProcState) {
20602                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20603                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20604                            // This process is a cached process holding activities...
20605                            // assign it the next cached value for that type, and then
20606                            // step that cached level.
20607                            app.curRawAdj = curCachedAdj;
20608                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20609                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20610                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20611                                    + ")");
20612                            if (curCachedAdj != nextCachedAdj) {
20613                                stepCached++;
20614                                if (stepCached >= cachedFactor) {
20615                                    stepCached = 0;
20616                                    curCachedAdj = nextCachedAdj;
20617                                    nextCachedAdj += 2;
20618                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20619                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20620                                    }
20621                                }
20622                            }
20623                            break;
20624                        default:
20625                            // For everything else, assign next empty cached process
20626                            // level and bump that up.  Note that this means that
20627                            // long-running services that have dropped down to the
20628                            // cached level will be treated as empty (since their process
20629                            // state is still as a service), which is what we want.
20630                            app.curRawAdj = curEmptyAdj;
20631                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20632                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20633                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20634                                    + ")");
20635                            if (curEmptyAdj != nextEmptyAdj) {
20636                                stepEmpty++;
20637                                if (stepEmpty >= emptyFactor) {
20638                                    stepEmpty = 0;
20639                                    curEmptyAdj = nextEmptyAdj;
20640                                    nextEmptyAdj += 2;
20641                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20642                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20643                                    }
20644                                }
20645                            }
20646                            break;
20647                    }
20648                }
20649
20650                applyOomAdjLocked(app, true, now, nowElapsed);
20651
20652                // Count the number of process types.
20653                switch (app.curProcState) {
20654                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20655                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20656                        mNumCachedHiddenProcs++;
20657                        numCached++;
20658                        if (numCached > cachedProcessLimit) {
20659                            app.kill("cached #" + numCached, true);
20660                        }
20661                        break;
20662                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20663                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20664                                && app.lastActivityTime < oldTime) {
20665                            app.kill("empty for "
20666                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20667                                    / 1000) + "s", true);
20668                        } else {
20669                            numEmpty++;
20670                            if (numEmpty > emptyProcessLimit) {
20671                                app.kill("empty #" + numEmpty, true);
20672                            }
20673                        }
20674                        break;
20675                    default:
20676                        mNumNonCachedProcs++;
20677                        break;
20678                }
20679
20680                if (app.isolated && app.services.size() <= 0) {
20681                    // If this is an isolated process, and there are no
20682                    // services running in it, then the process is no longer
20683                    // needed.  We agressively kill these because we can by
20684                    // definition not re-use the same process again, and it is
20685                    // good to avoid having whatever code was running in them
20686                    // left sitting around after no longer needed.
20687                    app.kill("isolated not needed", true);
20688                } else {
20689                    // Keeping this process, update its uid.
20690                    final UidRecord uidRec = app.uidRecord;
20691                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20692                        uidRec.curProcState = app.curProcState;
20693                    }
20694                }
20695
20696                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20697                        && !app.killedByAm) {
20698                    numTrimming++;
20699                }
20700            }
20701        }
20702
20703        mNumServiceProcs = mNewNumServiceProcs;
20704
20705        // Now determine the memory trimming level of background processes.
20706        // Unfortunately we need to start at the back of the list to do this
20707        // properly.  We only do this if the number of background apps we
20708        // are managing to keep around is less than half the maximum we desire;
20709        // if we are keeping a good number around, we'll let them use whatever
20710        // memory they want.
20711        final int numCachedAndEmpty = numCached + numEmpty;
20712        int memFactor;
20713        if (numCached <= ProcessList.TRIM_CACHED_APPS
20714                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20715            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20716                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20717            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20718                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20719            } else {
20720                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20721            }
20722        } else {
20723            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20724        }
20725        // We always allow the memory level to go up (better).  We only allow it to go
20726        // down if we are in a state where that is allowed, *and* the total number of processes
20727        // has gone down since last time.
20728        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20729                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20730                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20731        if (memFactor > mLastMemoryLevel) {
20732            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20733                memFactor = mLastMemoryLevel;
20734                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20735            }
20736        }
20737        if (memFactor != mLastMemoryLevel) {
20738            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20739        }
20740        mLastMemoryLevel = memFactor;
20741        mLastNumProcesses = mLruProcesses.size();
20742        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20743        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20744        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20745            if (mLowRamStartTime == 0) {
20746                mLowRamStartTime = now;
20747            }
20748            int step = 0;
20749            int fgTrimLevel;
20750            switch (memFactor) {
20751                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20752                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20753                    break;
20754                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20755                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20756                    break;
20757                default:
20758                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20759                    break;
20760            }
20761            int factor = numTrimming/3;
20762            int minFactor = 2;
20763            if (mHomeProcess != null) minFactor++;
20764            if (mPreviousProcess != null) minFactor++;
20765            if (factor < minFactor) factor = minFactor;
20766            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20767            for (int i=N-1; i>=0; i--) {
20768                ProcessRecord app = mLruProcesses.get(i);
20769                if (allChanged || app.procStateChanged) {
20770                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20771                    app.procStateChanged = false;
20772                }
20773                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20774                        && !app.killedByAm) {
20775                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20776                        try {
20777                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20778                                    "Trimming memory of " + app.processName + " to " + curLevel);
20779                            app.thread.scheduleTrimMemory(curLevel);
20780                        } catch (RemoteException e) {
20781                        }
20782                        if (false) {
20783                            // For now we won't do this; our memory trimming seems
20784                            // to be good enough at this point that destroying
20785                            // activities causes more harm than good.
20786                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20787                                    && app != mHomeProcess && app != mPreviousProcess) {
20788                                // Need to do this on its own message because the stack may not
20789                                // be in a consistent state at this point.
20790                                // For these apps we will also finish their activities
20791                                // to help them free memory.
20792                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20793                            }
20794                        }
20795                    }
20796                    app.trimMemoryLevel = curLevel;
20797                    step++;
20798                    if (step >= factor) {
20799                        step = 0;
20800                        switch (curLevel) {
20801                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20802                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20803                                break;
20804                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20805                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20806                                break;
20807                        }
20808                    }
20809                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20810                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20811                            && app.thread != null) {
20812                        try {
20813                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20814                                    "Trimming memory of heavy-weight " + app.processName
20815                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20816                            app.thread.scheduleTrimMemory(
20817                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20818                        } catch (RemoteException e) {
20819                        }
20820                    }
20821                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20822                } else {
20823                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20824                            || app.systemNoUi) && app.pendingUiClean) {
20825                        // If this application is now in the background and it
20826                        // had done UI, then give it the special trim level to
20827                        // have it free UI resources.
20828                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20829                        if (app.trimMemoryLevel < level && app.thread != null) {
20830                            try {
20831                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20832                                        "Trimming memory of bg-ui " + app.processName
20833                                        + " to " + level);
20834                                app.thread.scheduleTrimMemory(level);
20835                            } catch (RemoteException e) {
20836                            }
20837                        }
20838                        app.pendingUiClean = false;
20839                    }
20840                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20841                        try {
20842                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20843                                    "Trimming memory of fg " + app.processName
20844                                    + " to " + fgTrimLevel);
20845                            app.thread.scheduleTrimMemory(fgTrimLevel);
20846                        } catch (RemoteException e) {
20847                        }
20848                    }
20849                    app.trimMemoryLevel = fgTrimLevel;
20850                }
20851            }
20852        } else {
20853            if (mLowRamStartTime != 0) {
20854                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20855                mLowRamStartTime = 0;
20856            }
20857            for (int i=N-1; i>=0; i--) {
20858                ProcessRecord app = mLruProcesses.get(i);
20859                if (allChanged || app.procStateChanged) {
20860                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20861                    app.procStateChanged = false;
20862                }
20863                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20864                        || app.systemNoUi) && app.pendingUiClean) {
20865                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20866                            && app.thread != null) {
20867                        try {
20868                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20869                                    "Trimming memory of ui hidden " + app.processName
20870                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20871                            app.thread.scheduleTrimMemory(
20872                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20873                        } catch (RemoteException e) {
20874                        }
20875                    }
20876                    app.pendingUiClean = false;
20877                }
20878                app.trimMemoryLevel = 0;
20879            }
20880        }
20881
20882        if (mAlwaysFinishActivities) {
20883            // Need to do this on its own message because the stack may not
20884            // be in a consistent state at this point.
20885            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20886        }
20887
20888        if (allChanged) {
20889            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20890        }
20891
20892        // Update from any uid changes.
20893        for (int i=mActiveUids.size()-1; i>=0; i--) {
20894            final UidRecord uidRec = mActiveUids.valueAt(i);
20895            int uidChange = UidRecord.CHANGE_PROCSTATE;
20896            if (uidRec.setProcState != uidRec.curProcState) {
20897                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20898                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20899                        + " to " + uidRec.curProcState);
20900                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20901                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20902                        uidRec.lastBackgroundTime = nowElapsed;
20903                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20904                            // Note: the background settle time is in elapsed realtime, while
20905                            // the handler time base is uptime.  All this means is that we may
20906                            // stop background uids later than we had intended, but that only
20907                            // happens because the device was sleeping so we are okay anyway.
20908                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20909                        }
20910                    }
20911                } else {
20912                    if (uidRec.idle) {
20913                        uidChange = UidRecord.CHANGE_ACTIVE;
20914                        uidRec.idle = false;
20915                    }
20916                    uidRec.lastBackgroundTime = 0;
20917                }
20918                uidRec.setProcState = uidRec.curProcState;
20919                enqueueUidChangeLocked(uidRec, -1, uidChange);
20920                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20921            }
20922        }
20923
20924        if (mProcessStats.shouldWriteNowLocked(now)) {
20925            mHandler.post(new Runnable() {
20926                @Override public void run() {
20927                    synchronized (ActivityManagerService.this) {
20928                        mProcessStats.writeStateAsyncLocked();
20929                    }
20930                }
20931            });
20932        }
20933
20934        if (DEBUG_OOM_ADJ) {
20935            final long duration = SystemClock.uptimeMillis() - now;
20936            if (false) {
20937                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20938                        new RuntimeException("here").fillInStackTrace());
20939            } else {
20940                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20941            }
20942        }
20943    }
20944
20945    final void idleUids() {
20946        synchronized (this) {
20947            final long nowElapsed = SystemClock.elapsedRealtime();
20948            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20949            long nextTime = 0;
20950            for (int i=mActiveUids.size()-1; i>=0; i--) {
20951                final UidRecord uidRec = mActiveUids.valueAt(i);
20952                final long bgTime = uidRec.lastBackgroundTime;
20953                if (bgTime > 0 && !uidRec.idle) {
20954                    if (bgTime <= maxBgTime) {
20955                        uidRec.idle = true;
20956                        doStopUidLocked(uidRec.uid, uidRec);
20957                    } else {
20958                        if (nextTime == 0 || nextTime > bgTime) {
20959                            nextTime = bgTime;
20960                        }
20961                    }
20962                }
20963            }
20964            if (nextTime > 0) {
20965                mHandler.removeMessages(IDLE_UIDS_MSG);
20966                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20967                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20968            }
20969        }
20970    }
20971
20972    final void runInBackgroundDisabled(int uid) {
20973        synchronized (this) {
20974            UidRecord uidRec = mActiveUids.get(uid);
20975            if (uidRec != null) {
20976                // This uid is actually running...  should it be considered background now?
20977                if (uidRec.idle) {
20978                    doStopUidLocked(uidRec.uid, uidRec);
20979                }
20980            } else {
20981                // This uid isn't actually running...  still send a report about it being "stopped".
20982                doStopUidLocked(uid, null);
20983            }
20984        }
20985    }
20986
20987    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20988        mServices.stopInBackgroundLocked(uid);
20989        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20990    }
20991
20992    final void trimApplications() {
20993        synchronized (this) {
20994            int i;
20995
20996            // First remove any unused application processes whose package
20997            // has been removed.
20998            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20999                final ProcessRecord app = mRemovedProcesses.get(i);
21000                if (app.activities.size() == 0
21001                        && app.curReceiver == null && app.services.size() == 0) {
21002                    Slog.i(
21003                        TAG, "Exiting empty application process "
21004                        + app.toShortString() + " ("
21005                        + (app.thread != null ? app.thread.asBinder() : null)
21006                        + ")\n");
21007                    if (app.pid > 0 && app.pid != MY_PID) {
21008                        app.kill("empty", false);
21009                    } else {
21010                        try {
21011                            app.thread.scheduleExit();
21012                        } catch (Exception e) {
21013                            // Ignore exceptions.
21014                        }
21015                    }
21016                    cleanUpApplicationRecordLocked(app, false, true, -1);
21017                    mRemovedProcesses.remove(i);
21018
21019                    if (app.persistent) {
21020                        addAppLocked(app.info, false, null /* ABI override */);
21021                    }
21022                }
21023            }
21024
21025            // Now update the oom adj for all processes.
21026            updateOomAdjLocked();
21027        }
21028    }
21029
21030    /** This method sends the specified signal to each of the persistent apps */
21031    public void signalPersistentProcesses(int sig) throws RemoteException {
21032        if (sig != Process.SIGNAL_USR1) {
21033            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21034        }
21035
21036        synchronized (this) {
21037            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21038                    != PackageManager.PERMISSION_GRANTED) {
21039                throw new SecurityException("Requires permission "
21040                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21041            }
21042
21043            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21044                ProcessRecord r = mLruProcesses.get(i);
21045                if (r.thread != null && r.persistent) {
21046                    Process.sendSignal(r.pid, sig);
21047                }
21048            }
21049        }
21050    }
21051
21052    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21053        if (proc == null || proc == mProfileProc) {
21054            proc = mProfileProc;
21055            profileType = mProfileType;
21056            clearProfilerLocked();
21057        }
21058        if (proc == null) {
21059            return;
21060        }
21061        try {
21062            proc.thread.profilerControl(false, null, profileType);
21063        } catch (RemoteException e) {
21064            throw new IllegalStateException("Process disappeared");
21065        }
21066    }
21067
21068    private void clearProfilerLocked() {
21069        if (mProfileFd != null) {
21070            try {
21071                mProfileFd.close();
21072            } catch (IOException e) {
21073            }
21074        }
21075        mProfileApp = null;
21076        mProfileProc = null;
21077        mProfileFile = null;
21078        mProfileType = 0;
21079        mAutoStopProfiler = false;
21080        mSamplingInterval = 0;
21081    }
21082
21083    public boolean profileControl(String process, int userId, boolean start,
21084            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21085
21086        try {
21087            synchronized (this) {
21088                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21089                // its own permission.
21090                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21091                        != PackageManager.PERMISSION_GRANTED) {
21092                    throw new SecurityException("Requires permission "
21093                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21094                }
21095
21096                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21097                    throw new IllegalArgumentException("null profile info or fd");
21098                }
21099
21100                ProcessRecord proc = null;
21101                if (process != null) {
21102                    proc = findProcessLocked(process, userId, "profileControl");
21103                }
21104
21105                if (start && (proc == null || proc.thread == null)) {
21106                    throw new IllegalArgumentException("Unknown process: " + process);
21107                }
21108
21109                if (start) {
21110                    stopProfilerLocked(null, 0);
21111                    setProfileApp(proc.info, proc.processName, profilerInfo);
21112                    mProfileProc = proc;
21113                    mProfileType = profileType;
21114                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21115                    try {
21116                        fd = fd.dup();
21117                    } catch (IOException e) {
21118                        fd = null;
21119                    }
21120                    profilerInfo.profileFd = fd;
21121                    proc.thread.profilerControl(start, profilerInfo, profileType);
21122                    fd = null;
21123                    mProfileFd = null;
21124                } else {
21125                    stopProfilerLocked(proc, profileType);
21126                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21127                        try {
21128                            profilerInfo.profileFd.close();
21129                        } catch (IOException e) {
21130                        }
21131                    }
21132                }
21133
21134                return true;
21135            }
21136        } catch (RemoteException e) {
21137            throw new IllegalStateException("Process disappeared");
21138        } finally {
21139            if (profilerInfo != null && profilerInfo.profileFd != null) {
21140                try {
21141                    profilerInfo.profileFd.close();
21142                } catch (IOException e) {
21143                }
21144            }
21145        }
21146    }
21147
21148    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21149        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21150                userId, true, ALLOW_FULL_ONLY, callName, null);
21151        ProcessRecord proc = null;
21152        try {
21153            int pid = Integer.parseInt(process);
21154            synchronized (mPidsSelfLocked) {
21155                proc = mPidsSelfLocked.get(pid);
21156            }
21157        } catch (NumberFormatException e) {
21158        }
21159
21160        if (proc == null) {
21161            ArrayMap<String, SparseArray<ProcessRecord>> all
21162                    = mProcessNames.getMap();
21163            SparseArray<ProcessRecord> procs = all.get(process);
21164            if (procs != null && procs.size() > 0) {
21165                proc = procs.valueAt(0);
21166                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21167                    for (int i=1; i<procs.size(); i++) {
21168                        ProcessRecord thisProc = procs.valueAt(i);
21169                        if (thisProc.userId == userId) {
21170                            proc = thisProc;
21171                            break;
21172                        }
21173                    }
21174                }
21175            }
21176        }
21177
21178        return proc;
21179    }
21180
21181    public boolean dumpHeap(String process, int userId, boolean managed,
21182            String path, ParcelFileDescriptor fd) throws RemoteException {
21183
21184        try {
21185            synchronized (this) {
21186                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21187                // its own permission (same as profileControl).
21188                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21189                        != PackageManager.PERMISSION_GRANTED) {
21190                    throw new SecurityException("Requires permission "
21191                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21192                }
21193
21194                if (fd == null) {
21195                    throw new IllegalArgumentException("null fd");
21196                }
21197
21198                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21199                if (proc == null || proc.thread == null) {
21200                    throw new IllegalArgumentException("Unknown process: " + process);
21201                }
21202
21203                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21204                if (!isDebuggable) {
21205                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21206                        throw new SecurityException("Process not debuggable: " + proc);
21207                    }
21208                }
21209
21210                proc.thread.dumpHeap(managed, path, fd);
21211                fd = null;
21212                return true;
21213            }
21214        } catch (RemoteException e) {
21215            throw new IllegalStateException("Process disappeared");
21216        } finally {
21217            if (fd != null) {
21218                try {
21219                    fd.close();
21220                } catch (IOException e) {
21221                }
21222            }
21223        }
21224    }
21225
21226    @Override
21227    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21228            String reportPackage) {
21229        if (processName != null) {
21230            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21231                    "setDumpHeapDebugLimit()");
21232        } else {
21233            synchronized (mPidsSelfLocked) {
21234                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21235                if (proc == null) {
21236                    throw new SecurityException("No process found for calling pid "
21237                            + Binder.getCallingPid());
21238                }
21239                if (!Build.IS_DEBUGGABLE
21240                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21241                    throw new SecurityException("Not running a debuggable build");
21242                }
21243                processName = proc.processName;
21244                uid = proc.uid;
21245                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21246                    throw new SecurityException("Package " + reportPackage + " is not running in "
21247                            + proc);
21248                }
21249            }
21250        }
21251        synchronized (this) {
21252            if (maxMemSize > 0) {
21253                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21254            } else {
21255                if (uid != 0) {
21256                    mMemWatchProcesses.remove(processName, uid);
21257                } else {
21258                    mMemWatchProcesses.getMap().remove(processName);
21259                }
21260            }
21261        }
21262    }
21263
21264    @Override
21265    public void dumpHeapFinished(String path) {
21266        synchronized (this) {
21267            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21268                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21269                        + " does not match last pid " + mMemWatchDumpPid);
21270                return;
21271            }
21272            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21273                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21274                        + " does not match last path " + mMemWatchDumpFile);
21275                return;
21276            }
21277            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21278            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21279        }
21280    }
21281
21282    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21283    public void monitor() {
21284        synchronized (this) { }
21285    }
21286
21287    void onCoreSettingsChange(Bundle settings) {
21288        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21289            ProcessRecord processRecord = mLruProcesses.get(i);
21290            try {
21291                if (processRecord.thread != null) {
21292                    processRecord.thread.setCoreSettings(settings);
21293                }
21294            } catch (RemoteException re) {
21295                /* ignore */
21296            }
21297        }
21298    }
21299
21300    // Multi-user methods
21301
21302    /**
21303     * Start user, if its not already running, but don't bring it to foreground.
21304     */
21305    @Override
21306    public boolean startUserInBackground(final int userId) {
21307        return mUserController.startUser(userId, /* foreground */ false);
21308    }
21309
21310    @Override
21311    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21312        return mUserController.unlockUser(userId, token, secret, listener);
21313    }
21314
21315    @Override
21316    public boolean switchUser(final int targetUserId) {
21317        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21318        UserInfo currentUserInfo;
21319        UserInfo targetUserInfo;
21320        synchronized (this) {
21321            int currentUserId = mUserController.getCurrentUserIdLocked();
21322            currentUserInfo = mUserController.getUserInfo(currentUserId);
21323            targetUserInfo = mUserController.getUserInfo(targetUserId);
21324            if (targetUserInfo == null) {
21325                Slog.w(TAG, "No user info for user #" + targetUserId);
21326                return false;
21327            }
21328            if (!targetUserInfo.supportsSwitchTo()) {
21329                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21330                return false;
21331            }
21332            if (targetUserInfo.isManagedProfile()) {
21333                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21334                return false;
21335            }
21336            mUserController.setTargetUserIdLocked(targetUserId);
21337        }
21338        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21339        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21340        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21341        return true;
21342    }
21343
21344    void scheduleStartProfilesLocked() {
21345        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21346            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21347                    DateUtils.SECOND_IN_MILLIS);
21348        }
21349    }
21350
21351    @Override
21352    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21353        return mUserController.stopUser(userId, force, callback);
21354    }
21355
21356    @Override
21357    public UserInfo getCurrentUser() {
21358        return mUserController.getCurrentUser();
21359    }
21360
21361    @Override
21362    public boolean isUserRunning(int userId, int flags) {
21363        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21364                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21365            String msg = "Permission Denial: isUserRunning() from pid="
21366                    + Binder.getCallingPid()
21367                    + ", uid=" + Binder.getCallingUid()
21368                    + " requires " + INTERACT_ACROSS_USERS;
21369            Slog.w(TAG, msg);
21370            throw new SecurityException(msg);
21371        }
21372        synchronized (this) {
21373            return mUserController.isUserRunningLocked(userId, flags);
21374        }
21375    }
21376
21377    @Override
21378    public int[] getRunningUserIds() {
21379        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21380                != PackageManager.PERMISSION_GRANTED) {
21381            String msg = "Permission Denial: isUserRunning() from pid="
21382                    + Binder.getCallingPid()
21383                    + ", uid=" + Binder.getCallingUid()
21384                    + " requires " + INTERACT_ACROSS_USERS;
21385            Slog.w(TAG, msg);
21386            throw new SecurityException(msg);
21387        }
21388        synchronized (this) {
21389            return mUserController.getStartedUserArrayLocked();
21390        }
21391    }
21392
21393    @Override
21394    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21395        mUserController.registerUserSwitchObserver(observer);
21396    }
21397
21398    @Override
21399    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21400        mUserController.unregisterUserSwitchObserver(observer);
21401    }
21402
21403    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21404        if (info == null) return null;
21405        ApplicationInfo newInfo = new ApplicationInfo(info);
21406        newInfo.initForUser(userId);
21407        return newInfo;
21408    }
21409
21410    public boolean isUserStopped(int userId) {
21411        synchronized (this) {
21412            return mUserController.getStartedUserStateLocked(userId) == null;
21413        }
21414    }
21415
21416    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21417        if (aInfo == null
21418                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21419            return aInfo;
21420        }
21421
21422        ActivityInfo info = new ActivityInfo(aInfo);
21423        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21424        return info;
21425    }
21426
21427    private boolean processSanityChecksLocked(ProcessRecord process) {
21428        if (process == null || process.thread == null) {
21429            return false;
21430        }
21431
21432        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21433        if (!isDebuggable) {
21434            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21435                return false;
21436            }
21437        }
21438
21439        return true;
21440    }
21441
21442    public boolean startBinderTracking() throws RemoteException {
21443        synchronized (this) {
21444            mBinderTransactionTrackingEnabled = true;
21445            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21446            // permission (same as profileControl).
21447            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21448                    != PackageManager.PERMISSION_GRANTED) {
21449                throw new SecurityException("Requires permission "
21450                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21451            }
21452
21453            for (int i = 0; i < mLruProcesses.size(); i++) {
21454                ProcessRecord process = mLruProcesses.get(i);
21455                if (!processSanityChecksLocked(process)) {
21456                    continue;
21457                }
21458                try {
21459                    process.thread.startBinderTracking();
21460                } catch (RemoteException e) {
21461                    Log.v(TAG, "Process disappared");
21462                }
21463            }
21464            return true;
21465        }
21466    }
21467
21468    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21469        try {
21470            synchronized (this) {
21471                mBinderTransactionTrackingEnabled = false;
21472                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21473                // permission (same as profileControl).
21474                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21475                        != PackageManager.PERMISSION_GRANTED) {
21476                    throw new SecurityException("Requires permission "
21477                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21478                }
21479
21480                if (fd == null) {
21481                    throw new IllegalArgumentException("null fd");
21482                }
21483
21484                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21485                pw.println("Binder transaction traces for all processes.\n");
21486                for (ProcessRecord process : mLruProcesses) {
21487                    if (!processSanityChecksLocked(process)) {
21488                        continue;
21489                    }
21490
21491                    pw.println("Traces for process: " + process.processName);
21492                    pw.flush();
21493                    try {
21494                        TransferPipe tp = new TransferPipe();
21495                        try {
21496                            process.thread.stopBinderTrackingAndDump(
21497                                    tp.getWriteFd().getFileDescriptor());
21498                            tp.go(fd.getFileDescriptor());
21499                        } finally {
21500                            tp.kill();
21501                        }
21502                    } catch (IOException e) {
21503                        pw.println("Failure while dumping IPC traces from " + process +
21504                                ".  Exception: " + e);
21505                        pw.flush();
21506                    } catch (RemoteException e) {
21507                        pw.println("Got a RemoteException while dumping IPC traces from " +
21508                                process + ".  Exception: " + e);
21509                        pw.flush();
21510                    }
21511                }
21512                fd = null;
21513                return true;
21514            }
21515        } finally {
21516            if (fd != null) {
21517                try {
21518                    fd.close();
21519                } catch (IOException e) {
21520                }
21521            }
21522        }
21523    }
21524
21525    private final class LocalService extends ActivityManagerInternal {
21526        @Override
21527        public void onWakefulnessChanged(int wakefulness) {
21528            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21529        }
21530
21531        @Override
21532        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21533                String processName, String abiOverride, int uid, Runnable crashHandler) {
21534            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21535                    processName, abiOverride, uid, crashHandler);
21536        }
21537
21538        @Override
21539        public SleepToken acquireSleepToken(String tag) {
21540            Preconditions.checkNotNull(tag);
21541
21542            ComponentName requestedVrService = null;
21543            ComponentName callingVrActivity = null;
21544            int userId = -1;
21545            synchronized (ActivityManagerService.this) {
21546                if (mFocusedActivity != null) {
21547                    requestedVrService = mFocusedActivity.requestedVrComponent;
21548                    callingVrActivity = mFocusedActivity.info.getComponentName();
21549                    userId = mFocusedActivity.userId;
21550                }
21551            }
21552
21553            if (requestedVrService != null) {
21554                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21555            }
21556
21557            synchronized (ActivityManagerService.this) {
21558                SleepTokenImpl token = new SleepTokenImpl(tag);
21559                mSleepTokens.add(token);
21560                updateSleepIfNeededLocked();
21561                return token;
21562            }
21563        }
21564
21565        @Override
21566        public ComponentName getHomeActivityForUser(int userId) {
21567            synchronized (ActivityManagerService.this) {
21568                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21569                return homeActivity == null ? null : homeActivity.realActivity;
21570            }
21571        }
21572
21573        @Override
21574        public void onUserRemoved(int userId) {
21575            synchronized (ActivityManagerService.this) {
21576                ActivityManagerService.this.onUserStoppedLocked(userId);
21577            }
21578        }
21579
21580        @Override
21581        public void onLocalVoiceInteractionStarted(IBinder activity,
21582                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21583            synchronized (ActivityManagerService.this) {
21584                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21585                        voiceSession, voiceInteractor);
21586            }
21587        }
21588
21589        @Override
21590        public void notifyStartingWindowDrawn() {
21591            synchronized (ActivityManagerService.this) {
21592                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21593            }
21594        }
21595
21596        @Override
21597        public void notifyAppTransitionStarting(int reason) {
21598            synchronized (ActivityManagerService.this) {
21599                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21600            }
21601        }
21602
21603        @Override
21604        public void notifyAppTransitionFinished() {
21605            synchronized (ActivityManagerService.this) {
21606                mStackSupervisor.notifyAppTransitionDone();
21607            }
21608        }
21609
21610        @Override
21611        public void notifyAppTransitionCancelled() {
21612            synchronized (ActivityManagerService.this) {
21613                mStackSupervisor.notifyAppTransitionDone();
21614            }
21615        }
21616
21617        @Override
21618        public List<IBinder> getTopVisibleActivities() {
21619            synchronized (ActivityManagerService.this) {
21620                return mStackSupervisor.getTopVisibleActivities();
21621            }
21622        }
21623
21624        @Override
21625        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21626            synchronized (ActivityManagerService.this) {
21627                mStackSupervisor.setDockedStackMinimized(minimized);
21628            }
21629        }
21630
21631        @Override
21632        public void killForegroundAppsForUser(int userHandle) {
21633            synchronized (ActivityManagerService.this) {
21634                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21635                final int NP = mProcessNames.getMap().size();
21636                for (int ip = 0; ip < NP; ip++) {
21637                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21638                    final int NA = apps.size();
21639                    for (int ia = 0; ia < NA; ia++) {
21640                        final ProcessRecord app = apps.valueAt(ia);
21641                        if (app.persistent) {
21642                            // We don't kill persistent processes.
21643                            continue;
21644                        }
21645                        if (app.removed) {
21646                            procs.add(app);
21647                        } else if (app.userId == userHandle && app.foregroundActivities) {
21648                            app.removed = true;
21649                            procs.add(app);
21650                        }
21651                    }
21652                }
21653
21654                final int N = procs.size();
21655                for (int i = 0; i < N; i++) {
21656                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21657                }
21658            }
21659        }
21660
21661        @Override
21662        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21663            if (!(target instanceof PendingIntentRecord)) {
21664                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21665                return;
21666            }
21667            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21668        }
21669    }
21670
21671    private final class SleepTokenImpl extends SleepToken {
21672        private final String mTag;
21673        private final long mAcquireTime;
21674
21675        public SleepTokenImpl(String tag) {
21676            mTag = tag;
21677            mAcquireTime = SystemClock.uptimeMillis();
21678        }
21679
21680        @Override
21681        public void release() {
21682            synchronized (ActivityManagerService.this) {
21683                if (mSleepTokens.remove(this)) {
21684                    updateSleepIfNeededLocked();
21685                }
21686            }
21687        }
21688
21689        @Override
21690        public String toString() {
21691            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21692        }
21693    }
21694
21695    /**
21696     * An implementation of IAppTask, that allows an app to manage its own tasks via
21697     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21698     * only the process that calls getAppTasks() can call the AppTask methods.
21699     */
21700    class AppTaskImpl extends IAppTask.Stub {
21701        private int mTaskId;
21702        private int mCallingUid;
21703
21704        public AppTaskImpl(int taskId, int callingUid) {
21705            mTaskId = taskId;
21706            mCallingUid = callingUid;
21707        }
21708
21709        private void checkCaller() {
21710            if (mCallingUid != Binder.getCallingUid()) {
21711                throw new SecurityException("Caller " + mCallingUid
21712                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21713            }
21714        }
21715
21716        @Override
21717        public void finishAndRemoveTask() {
21718            checkCaller();
21719
21720            synchronized (ActivityManagerService.this) {
21721                long origId = Binder.clearCallingIdentity();
21722                try {
21723                    // We remove the task from recents to preserve backwards
21724                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21725                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21726                    }
21727                } finally {
21728                    Binder.restoreCallingIdentity(origId);
21729                }
21730            }
21731        }
21732
21733        @Override
21734        public ActivityManager.RecentTaskInfo getTaskInfo() {
21735            checkCaller();
21736
21737            synchronized (ActivityManagerService.this) {
21738                long origId = Binder.clearCallingIdentity();
21739                try {
21740                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21741                    if (tr == null) {
21742                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21743                    }
21744                    return createRecentTaskInfoFromTaskRecord(tr);
21745                } finally {
21746                    Binder.restoreCallingIdentity(origId);
21747                }
21748            }
21749        }
21750
21751        @Override
21752        public void moveToFront() {
21753            checkCaller();
21754            // Will bring task to front if it already has a root activity.
21755            final long origId = Binder.clearCallingIdentity();
21756            try {
21757                synchronized (this) {
21758                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21759                }
21760            } finally {
21761                Binder.restoreCallingIdentity(origId);
21762            }
21763        }
21764
21765        @Override
21766        public int startActivity(IBinder whoThread, String callingPackage,
21767                Intent intent, String resolvedType, Bundle bOptions) {
21768            checkCaller();
21769
21770            int callingUser = UserHandle.getCallingUserId();
21771            TaskRecord tr;
21772            IApplicationThread appThread;
21773            synchronized (ActivityManagerService.this) {
21774                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21775                if (tr == null) {
21776                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21777                }
21778                appThread = ApplicationThreadNative.asInterface(whoThread);
21779                if (appThread == null) {
21780                    throw new IllegalArgumentException("Bad app thread " + appThread);
21781                }
21782            }
21783            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21784                    resolvedType, null, null, null, null, 0, 0, null, null,
21785                    null, bOptions, false, callingUser, null, tr);
21786        }
21787
21788        @Override
21789        public void setExcludeFromRecents(boolean exclude) {
21790            checkCaller();
21791
21792            synchronized (ActivityManagerService.this) {
21793                long origId = Binder.clearCallingIdentity();
21794                try {
21795                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21796                    if (tr == null) {
21797                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21798                    }
21799                    Intent intent = tr.getBaseIntent();
21800                    if (exclude) {
21801                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21802                    } else {
21803                        intent.setFlags(intent.getFlags()
21804                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21805                    }
21806                } finally {
21807                    Binder.restoreCallingIdentity(origId);
21808                }
21809            }
21810        }
21811    }
21812
21813    /**
21814     * Kill processes for the user with id userId and that depend on the package named packageName
21815     */
21816    @Override
21817    public void killPackageDependents(String packageName, int userId) {
21818        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21819        if (packageName == null) {
21820            throw new NullPointerException(
21821                    "Cannot kill the dependents of a package without its name.");
21822        }
21823
21824        long callingId = Binder.clearCallingIdentity();
21825        IPackageManager pm = AppGlobals.getPackageManager();
21826        int pkgUid = -1;
21827        try {
21828            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21829        } catch (RemoteException e) {
21830        }
21831        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21832            throw new IllegalArgumentException(
21833                    "Cannot kill dependents of non-existing package " + packageName);
21834        }
21835        try {
21836            synchronized(this) {
21837                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21838                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21839                        "dep: " + packageName);
21840            }
21841        } finally {
21842            Binder.restoreCallingIdentity(callingId);
21843        }
21844    }
21845}
21846