ActivityManagerService.java revision c88368c270504ff93f415da33b40aa32d36a1f60
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.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.LockGuard;
49import com.android.server.ServiceThread;
50import com.android.server.SystemService;
51import com.android.server.SystemServiceManager;
52import com.android.server.Watchdog;
53import com.android.server.am.ActivityStack.ActivityState;
54import com.android.server.firewall.IntentFirewall;
55import com.android.server.pm.Installer;
56import com.android.server.pm.Installer.InstallerException;
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.Manifest.permission;
67import android.annotation.NonNull;
68import android.annotation.UserIdInt;
69import android.app.Activity;
70import android.app.ActivityManager;
71import android.app.ActivityManager.RunningTaskInfo;
72import android.app.ActivityManager.StackId;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManager.TaskThumbnailInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerInternal.SleepToken;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.AppOpsManager;
83import android.app.ApplicationErrorReport;
84import android.app.ApplicationThreadNative;
85import android.app.BroadcastOptions;
86import android.app.Dialog;
87import android.app.IActivityContainer;
88import android.app.IActivityContainerCallback;
89import android.app.IActivityController;
90import android.app.IAppTask;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.ITaskStackListener;
98import android.app.IUiAutomationConnection;
99import android.app.IUidObserver;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.provider.Downloads;
194import android.os.storage.IMountService;
195import android.os.storage.MountServiceInternal;
196import android.os.storage.StorageManager;
197import android.provider.Settings;
198import android.service.voice.IVoiceInteractionSession;
199import android.service.voice.VoiceInteractionManagerInternal;
200import android.service.voice.VoiceInteractionSession;
201import android.telecom.TelecomManager;
202import android.text.format.DateUtils;
203import android.text.format.Time;
204import android.text.style.SuggestionSpan;
205import android.util.ArrayMap;
206import android.util.ArraySet;
207import android.util.AtomicFile;
208import android.util.DebugUtils;
209import android.util.DisplayMetrics;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Display;
219import android.view.Gravity;
220import android.view.LayoutInflater;
221import android.view.View;
222import android.view.WindowManager;
223
224import java.io.File;
225import java.io.FileDescriptor;
226import java.io.FileInputStream;
227import java.io.FileNotFoundException;
228import java.io.FileOutputStream;
229import java.io.IOException;
230import java.io.InputStreamReader;
231import java.io.PrintWriter;
232import java.io.StringWriter;
233import java.lang.ref.WeakReference;
234import java.nio.charset.StandardCharsets;
235import java.util.ArrayList;
236import java.util.Arrays;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.HashMap;
240import java.util.HashSet;
241import java.util.Iterator;
242import java.util.List;
243import java.util.Locale;
244import java.util.Map;
245import java.util.Objects;
246import java.util.Set;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicLong;
249
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270import static android.content.pm.PackageManager.GET_PROVIDERS;
271import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278import static android.os.Process.PROC_CHAR;
279import static android.os.Process.PROC_OUT_LONG;
280import static android.os.Process.PROC_PARENS;
281import static android.os.Process.PROC_SPACE_TERM;
282import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283import static android.provider.Settings.Global.DEBUG_APP;
284import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289import static android.provider.Settings.System.FONT_SCALE;
290import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291import static com.android.internal.util.XmlUtils.readIntAttribute;
292import static com.android.internal.util.XmlUtils.readLongAttribute;
293import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294import static com.android.internal.util.XmlUtils.writeIntAttribute;
295import static com.android.internal.util.XmlUtils.writeLongAttribute;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374public final class ActivityManagerService extends ActivityManagerNative
375        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386    private static final String TAG_LRU = TAG + POSTFIX_LRU;
387    private static final String TAG_MU = TAG + POSTFIX_MU;
388    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389    private static final String TAG_POWER = TAG + POSTFIX_POWER;
390    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393    private static final String TAG_PSS = TAG + POSTFIX_PSS;
394    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396    private static final String TAG_STACK = TAG + POSTFIX_STACK;
397    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404    // here so that while the job scheduler can depend on AMS, the other way around
405    // need not be the case.
406    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408    /** Control over CPU and battery monitoring */
409    // write battery stats every 30 minutes.
410    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411    static final boolean MONITOR_CPU_USAGE = true;
412    // don't sample cpu less than every 5 seconds.
413    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414    // wait possibly forever for next cpu sample.
415    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416    static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418    // The flags that are set for all calls we make to the package manager.
419    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425    // Amount of time after a call to stopAppSwitches() during which we will
426    // prevent further untrusted switches from happening.
427    static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429    // How long we wait for a launched process to attach to the activity manager
430    // before we decide it's never going to come up for real.
431    static final int PROC_START_TIMEOUT = 10*1000;
432    // How long we wait for an attached process to publish its content providers
433    // before we decide it must be hung.
434    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436    // How long we will retain processes hosting content providers in the "last activity"
437    // state before allowing them to drop down to the regular cached LRU list.  This is
438    // to avoid thrashing of provider processes under low memory situations.
439    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441    // How long we wait for a launched process to attach to the activity manager
442    // before we decide it's never going to come up for real, when the process was
443    // started with a wrapper for instrumentation (such as Valgrind) because it
444    // could take much longer than usual.
445    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447    // How long to wait after going idle before forcing apps to GC.
448    static final int GC_TIMEOUT = 5*1000;
449
450    // The minimum amount of time between successive GC requests for a process.
451    static final int GC_MIN_INTERVAL = 60*1000;
452
453    // The minimum amount of time between successive PSS requests for a process.
454    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456    // The minimum amount of time between successive PSS requests for a process
457    // when the request is due to the memory state being lowered.
458    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460    // The rate at which we check for apps using excessive power -- 15 mins.
461    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463    // The minimum sample duration we will allow before deciding we have
464    // enough data on wake locks to start killing things.
465    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467    // The minimum sample duration we will allow before deciding we have
468    // enough data on CPU usage to start killing things.
469    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471    // How long we allow a receiver to run before giving up on it.
472    static final int BROADCAST_FG_TIMEOUT = 10*1000;
473    static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475    // How long we wait until we timeout on key dispatching.
476    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478    // How long we wait until we timeout on key dispatching during instrumentation.
479    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481    // This is the amount of time an app needs to be running a foreground service before
482    // we will consider it to be doing interaction for usage stats.
483    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485    // Maximum amount of time we will allow to elapse before re-reporting usage stats
486    // interaction with foreground processes.
487    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489    // This is the amount of time we allow an app to settle after it goes into the background,
490    // before we start restricting what it can do.
491    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493    // How long to wait in getAssistContextExtras for the activity and foreground services
494    // to respond with the result.
495    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497    // How long top wait when going through the modern assist (which doesn't need to block
498    // on getting this result before starting to launch its UI).
499    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501    // Maximum number of persisted Uri grants a package is allowed
502    static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504    static final int MY_PID = Process.myPid();
505
506    static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508    // How many bytes to write into the dropbox log before truncating
509    static final int DROPBOX_MAX_SIZE = 192 * 1024;
510    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511    // as one line, but close enough for now.
512    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514    // Access modes for handleIncomingUser.
515    static final int ALLOW_NON_FULL = 0;
516    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517    static final int ALLOW_FULL_ONLY = 2;
518
519    // Delay in notifying task stack change listeners (in millis)
520    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522    // Necessary ApplicationInfo flags to mark an app as persistent
523    private static final int PERSISTENT_MASK =
524            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526    // Intent sent when remote bugreport collection has been completed
527    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530    // Delay to disable app launch boost
531    static final int APP_BOOST_MESSAGE_DELAY = 3000;
532    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533    static final int APP_BOOST_TIMEOUT = 2500;
534
535    // Used to indicate that a task is removed it should also be removed from recents.
536    private static final boolean REMOVE_FROM_RECENTS = true;
537    // Used to indicate that an app transition should be animated.
538    static final boolean ANIMATE = true;
539
540    // Determines whether to take full screen screenshots
541    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544    private static native int nativeMigrateToBoost();
545    private static native int nativeMigrateFromBoost();
546    private boolean mIsBoosted = false;
547    private long mBoostStartTime = 0;
548
549    /** All system services */
550    SystemServiceManager mSystemServiceManager;
551
552    private Installer mInstaller;
553
554    /** Run all ActivityStacks through this */
555    final ActivityStackSupervisor mStackSupervisor;
556
557    final ActivityStarter mActivityStarter;
558
559    /** Task stack change listeners. */
560    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561            new RemoteCallbackList<ITaskStackListener>();
562
563    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565    public IntentFirewall mIntentFirewall;
566
567    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568    // default actuion automatically.  Important for devices without direct input
569    // devices.
570    private boolean mShowDialogs = true;
571    private boolean mInVrMode = false;
572
573    // Whether we should use SCHED_FIFO for UI and RenderThreads.
574    private boolean mUseFifoUiScheduling = false;
575
576    BroadcastQueue mFgBroadcastQueue;
577    BroadcastQueue mBgBroadcastQueue;
578    // Convenient for easy iteration over the queues. Foreground is first
579    // so that dispatch of foreground broadcasts gets precedence.
580    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582    BroadcastStats mLastBroadcastStats;
583    BroadcastStats mCurBroadcastStats;
584
585    BroadcastQueue broadcastQueueForIntent(Intent intent) {
586        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                "Broadcast intent " + intent + " on "
589                + (isFg ? "foreground" : "background") + " queue");
590        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591    }
592
593    /**
594     * Activity we have told the window manager to have key focus.
595     */
596    ActivityRecord mFocusedActivity = null;
597
598    /**
599     * User id of the last activity mFocusedActivity was set to.
600     */
601    private int mLastFocusedUserId;
602
603    /**
604     * If non-null, we are tracking the time the user spends in the currently focused app.
605     */
606    private AppTimeTracker mCurAppTimeTracker;
607
608    /**
609     * List of intents that were used to start the most recent tasks.
610     */
611    final RecentTasks mRecentTasks;
612
613    /**
614     * For addAppTask: cached of the last activity component that was added.
615     */
616    ComponentName mLastAddedTaskComponent;
617
618    /**
619     * For addAppTask: cached of the last activity uid that was added.
620     */
621    int mLastAddedTaskUid;
622
623    /**
624     * For addAppTask: cached of the last ActivityInfo that was added.
625     */
626    ActivityInfo mLastAddedTaskActivity;
627
628    /**
629     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630     */
631    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633    /**
634     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635     */
636    String mDeviceOwnerName;
637
638    final UserController mUserController;
639
640    final AppErrors mAppErrors;
641
642    boolean mDoingSetFocusedActivity;
643
644    public boolean canShowErrorDialogs() {
645        return mShowDialogs && !mSleeping && !mShuttingDown
646                && mLockScreenShown != LOCK_SCREEN_SHOWN;
647    }
648
649    private static final class PriorityState {
650        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651        // the current thread is currently in. When it drops down to zero, we will no longer boost
652        // the thread's priority.
653        private int regionCounter = 0;
654
655        // The thread's previous priority before boosting.
656        private int prevPriority = Integer.MIN_VALUE;
657    }
658
659    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660        @Override protected PriorityState initialValue() {
661            return new PriorityState();
662        }
663    };
664
665    static void boostPriorityForLockedSection() {
666        int tid = Process.myTid();
667        int prevPriority = Process.getThreadPriority(tid);
668        PriorityState state = sThreadPriorityState.get();
669        if (state.regionCounter == 0 && prevPriority > -2) {
670            state.prevPriority = prevPriority;
671            Process.setThreadPriority(tid, -2);
672        }
673        state.regionCounter++;
674    }
675
676    static void resetPriorityAfterLockedSection() {
677        PriorityState state = sThreadPriorityState.get();
678        state.regionCounter--;
679        if (state.regionCounter == 0 && state.prevPriority > -2) {
680            Process.setThreadPriority(Process.myTid(), state.prevPriority);
681        }
682    }
683
684    public class PendingAssistExtras extends Binder implements Runnable {
685        public final ActivityRecord activity;
686        public final Bundle extras;
687        public final Intent intent;
688        public final String hint;
689        public final IResultReceiver receiver;
690        public final int userHandle;
691        public boolean haveResult = false;
692        public Bundle result = null;
693        public AssistStructure structure = null;
694        public AssistContent content = null;
695        public Bundle receiverExtras;
696
697        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699            activity = _activity;
700            extras = _extras;
701            intent = _intent;
702            hint = _hint;
703            receiver = _receiver;
704            receiverExtras = _receiverExtras;
705            userHandle = _userHandle;
706        }
707        @Override
708        public void run() {
709            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710            synchronized (this) {
711                haveResult = true;
712                notifyAll();
713            }
714            pendingAssistExtrasTimedOut(this);
715        }
716    }
717
718    final ArrayList<PendingAssistExtras> mPendingAssistExtras
719            = new ArrayList<PendingAssistExtras>();
720
721    /**
722     * Process management.
723     */
724    final ProcessList mProcessList = new ProcessList();
725
726    /**
727     * All of the applications we currently have running organized by name.
728     * The keys are strings of the application package name (as
729     * returned by the package manager), and the keys are ApplicationRecord
730     * objects.
731     */
732    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734    /**
735     * Tracking long-term execution of processes to look for abuse and other
736     * bad app behavior.
737     */
738    final ProcessStatsService mProcessStats;
739
740    /**
741     * The currently running isolated processes.
742     */
743    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745    /**
746     * Counter for assigning isolated process uids, to avoid frequently reusing the
747     * same ones.
748     */
749    int mNextIsolatedProcessUid = 0;
750
751    /**
752     * The currently running heavy-weight process, if any.
753     */
754    ProcessRecord mHeavyWeightProcess = null;
755
756    /**
757     * All of the processes we currently have running organized by pid.
758     * The keys are the pid running the application.
759     *
760     * <p>NOTE: This object is protected by its own lock, NOT the global
761     * activity manager lock!
762     */
763    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765    /**
766     * All of the processes that have been forced to be foreground.  The key
767     * is the pid of the caller who requested it (we hold a death
768     * link on it).
769     */
770    abstract class ForegroundToken implements IBinder.DeathRecipient {
771        int pid;
772        IBinder token;
773    }
774    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776    /**
777     * List of records for processes that someone had tried to start before the
778     * system was ready.  We don't start them at that point, but ensure they
779     * are started by the time booting is complete.
780     */
781    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783    /**
784     * List of persistent applications that are in the process
785     * of being started.
786     */
787    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes that are being forcibly torn down.
791     */
792    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794    /**
795     * List of running applications, sorted by recent usage.
796     * The first entry in the list is the least recently used.
797     */
798    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800    /**
801     * Where in mLruProcesses that the processes hosting activities start.
802     */
803    int mLruProcessActivityStart = 0;
804
805    /**
806     * Where in mLruProcesses that the processes hosting services start.
807     * This is after (lower index) than mLruProcessesActivityStart.
808     */
809    int mLruProcessServiceStart = 0;
810
811    /**
812     * List of processes that should gc as soon as things are idle.
813     */
814    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816    /**
817     * Processes we want to collect PSS data from.
818     */
819    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821    private boolean mBinderTransactionTrackingEnabled = false;
822
823    /**
824     * Last time we requested PSS data of all processes.
825     */
826    long mLastFullPssTime = SystemClock.uptimeMillis();
827
828    /**
829     * If set, the next time we collect PSS data we should do a full collection
830     * with data from native processes and the kernel.
831     */
832    boolean mFullPssPending = false;
833
834    /**
835     * This is the process holding what we currently consider to be
836     * the "home" activity.
837     */
838    ProcessRecord mHomeProcess;
839
840    /**
841     * This is the process holding the activity the user last visited that
842     * is in a different process from the one they are currently in.
843     */
844    ProcessRecord mPreviousProcess;
845
846    /**
847     * The time at which the previous process was last visible.
848     */
849    long mPreviousProcessVisibleTime;
850
851    /**
852     * Track all uids that have actively running processes.
853     */
854    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856    /**
857     * This is for verifying the UID report flow.
858     */
859    static final boolean VALIDATE_UID_STATES = true;
860    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862    /**
863     * Packages that the user has asked to have run in screen size
864     * compatibility mode instead of filling the screen.
865     */
866    final CompatModePackages mCompatModePackages;
867
868    /**
869     * Set of IntentSenderRecord objects that are currently active.
870     */
871    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874    /**
875     * Fingerprints (hashCode()) of stack traces that we've
876     * already logged DropBox entries for.  Guarded by itself.  If
877     * something (rogue user app) forces this over
878     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879     */
880    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883    /**
884     * Strict Mode background batched logging state.
885     *
886     * The string buffer is guarded by itself, and its lock is also
887     * used to determine if another batched write is already
888     * in-flight.
889     */
890    private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892    /**
893     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895     */
896    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898    /**
899     * Resolver for broadcast intents to registered receivers.
900     * Holds BroadcastFilter (subclass of IntentFilter).
901     */
902    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904        @Override
905        protected boolean allowFilterResult(
906                BroadcastFilter filter, List<BroadcastFilter> dest) {
907            IBinder target = filter.receiverList.receiver.asBinder();
908            for (int i = dest.size() - 1; i >= 0; i--) {
909                if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                    return false;
911                }
912            }
913            return true;
914        }
915
916        @Override
917        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                    || userId == filter.owningUserId) {
920                return super.newResult(filter, match, userId);
921            }
922            return null;
923        }
924
925        @Override
926        protected BroadcastFilter[] newArray(int size) {
927            return new BroadcastFilter[size];
928        }
929
930        @Override
931        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932            return packageName.equals(filter.packageName);
933        }
934    };
935
936    /**
937     * State of all active sticky broadcasts per user.  Keys are the action of the
938     * sticky Intent, values are an ArrayList of all broadcasted intents with
939     * that action (which should usually be one).  The SparseArray is keyed
940     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941     * for stickies that are sent to all users.
942     */
943    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946    final ActiveServices mServices;
947
948    final static class Association {
949        final int mSourceUid;
950        final String mSourceProcess;
951        final int mTargetUid;
952        final ComponentName mTargetComponent;
953        final String mTargetProcess;
954
955        int mCount;
956        long mTime;
957
958        int mNesting;
959        long mStartTime;
960
961        // states of the source process when the bind occurred.
962        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963        long mLastStateUptime;
964        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                - ActivityManager.MIN_PROCESS_STATE+1];
966
967        Association(int sourceUid, String sourceProcess, int targetUid,
968                ComponentName targetComponent, String targetProcess) {
969            mSourceUid = sourceUid;
970            mSourceProcess = sourceProcess;
971            mTargetUid = targetUid;
972            mTargetComponent = targetComponent;
973            mTargetProcess = targetProcess;
974        }
975    }
976
977    /**
978     * When service association tracking is enabled, this is all of the associations we
979     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980     * -> association data.
981     */
982    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983            mAssociations = new SparseArray<>();
984    boolean mTrackingAssociations;
985
986    /**
987     * Backup/restore process management
988     */
989    String mBackupAppName = null;
990    BackupRecord mBackupTarget = null;
991
992    final ProviderMap mProviderMap;
993
994    /**
995     * List of content providers who have clients waiting for them.  The
996     * application is currently being launched and the provider will be
997     * removed from this list once it is published.
998     */
999    final ArrayList<ContentProviderRecord> mLaunchingProviders
1000            = new ArrayList<ContentProviderRecord>();
1001
1002    /**
1003     * File storing persisted {@link #mGrantedUriPermissions}.
1004     */
1005    private final AtomicFile mGrantFile;
1006
1007    /** XML constants used in {@link #mGrantFile} */
1008    private static final String TAG_URI_GRANTS = "uri-grants";
1009    private static final String TAG_URI_GRANT = "uri-grant";
1010    private static final String ATTR_USER_HANDLE = "userHandle";
1011    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014    private static final String ATTR_TARGET_PKG = "targetPkg";
1015    private static final String ATTR_URI = "uri";
1016    private static final String ATTR_MODE_FLAGS = "modeFlags";
1017    private static final String ATTR_CREATED_TIME = "createdTime";
1018    private static final String ATTR_PREFIX = "prefix";
1019
1020    /**
1021     * Global set of specific {@link Uri} permissions that have been granted.
1022     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023     * to {@link UriPermission#uri} to {@link UriPermission}.
1024     */
1025    @GuardedBy("this")
1026    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029    public static class GrantUri {
1030        public final int sourceUserId;
1031        public final Uri uri;
1032        public boolean prefix;
1033
1034        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035            this.sourceUserId = sourceUserId;
1036            this.uri = uri;
1037            this.prefix = prefix;
1038        }
1039
1040        @Override
1041        public int hashCode() {
1042            int hashCode = 1;
1043            hashCode = 31 * hashCode + sourceUserId;
1044            hashCode = 31 * hashCode + uri.hashCode();
1045            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046            return hashCode;
1047        }
1048
1049        @Override
1050        public boolean equals(Object o) {
1051            if (o instanceof GrantUri) {
1052                GrantUri other = (GrantUri) o;
1053                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                        && prefix == other.prefix;
1055            }
1056            return false;
1057        }
1058
1059        @Override
1060        public String toString() {
1061            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062            if (prefix) result += " [prefix]";
1063            return result;
1064        }
1065
1066        public String toSafeString() {
1067            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068            if (prefix) result += " [prefix]";
1069            return result;
1070        }
1071
1072        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                    ContentProvider.getUriWithoutUserId(uri), false);
1075        }
1076    }
1077
1078    CoreSettingsObserver mCoreSettingsObserver;
1079
1080    FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082    private final class FontScaleSettingObserver extends ContentObserver {
1083        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085        public FontScaleSettingObserver() {
1086            super(mHandler);
1087            ContentResolver resolver = mContext.getContentResolver();
1088            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089        }
1090
1091        @Override
1092        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093            if (mFontScaleUri.equals(uri)) {
1094                updateFontScaleIfNeeded(userId);
1095            }
1096        }
1097    }
1098
1099    /**
1100     * Thread-local storage used to carry caller permissions over through
1101     * indirect content-provider access.
1102     */
1103    private class Identity {
1104        public final IBinder token;
1105        public final int pid;
1106        public final int uid;
1107
1108        Identity(IBinder _token, int _pid, int _uid) {
1109            token = _token;
1110            pid = _pid;
1111            uid = _uid;
1112        }
1113    }
1114
1115    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117    /**
1118     * All information we have collected about the runtime performance of
1119     * any user id that can impact battery performance.
1120     */
1121    final BatteryStatsService mBatteryStatsService;
1122
1123    /**
1124     * Information about component usage
1125     */
1126    UsageStatsManagerInternal mUsageStatsService;
1127
1128    /**
1129     * Access to DeviceIdleController service.
1130     */
1131    DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133    /**
1134     * Information about and control over application operations
1135     */
1136    final AppOpsService mAppOpsService;
1137
1138    /**
1139     * Current configuration information.  HistoryRecord objects are given
1140     * a reference to this object to indicate which configuration they are
1141     * currently running in, so this object must be kept immutable.
1142     */
1143    Configuration mConfiguration = new Configuration();
1144
1145    /**
1146     * Current sequencing integer of the configuration, for skipping old
1147     * configurations.
1148     */
1149    int mConfigurationSeq = 0;
1150
1151    boolean mSuppressResizeConfigChanges = false;
1152
1153    /**
1154     * Hardware-reported OpenGLES version.
1155     */
1156    final int GL_ES_VERSION;
1157
1158    /**
1159     * List of initialization arguments to pass to all processes when binding applications to them.
1160     * For example, references to the commonly used services.
1161     */
1162    HashMap<String, IBinder> mAppBindArgs;
1163    HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165    /**
1166     * Temporary to avoid allocations.  Protected by main lock.
1167     */
1168    final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170    /**
1171     * Used to control how we initialize the service.
1172     */
1173    ComponentName mTopComponent;
1174    String mTopAction = Intent.ACTION_MAIN;
1175    String mTopData;
1176
1177    volatile boolean mProcessesReady = false;
1178    volatile boolean mSystemReady = false;
1179    volatile boolean mOnBattery = false;
1180    volatile int mFactoryTest;
1181
1182    @GuardedBy("this") boolean mBooting = false;
1183    @GuardedBy("this") boolean mCallFinishBooting = false;
1184    @GuardedBy("this") boolean mBootAnimationComplete = false;
1185    @GuardedBy("this") boolean mLaunchWarningShown = false;
1186    @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188    Context mContext;
1189
1190    /**
1191     * The time at which we will allow normal application switches again,
1192     * after a call to {@link #stopAppSwitches()}.
1193     */
1194    long mAppSwitchesAllowedTime;
1195
1196    /**
1197     * This is set to true after the first switch after mAppSwitchesAllowedTime
1198     * is set; any switches after that will clear the time.
1199     */
1200    boolean mDidAppSwitch;
1201
1202    /**
1203     * Last time (in realtime) at which we checked for power usage.
1204     */
1205    long mLastPowerCheckRealtime;
1206
1207    /**
1208     * Last time (in uptime) at which we checked for power usage.
1209     */
1210    long mLastPowerCheckUptime;
1211
1212    /**
1213     * Set while we are wanting to sleep, to prevent any
1214     * activities from being started/resumed.
1215     *
1216     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1217     *
1218     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1219     * while in the sleep state until there is a pending transition out of sleep, in which case
1220     * mSleeping is set to false, and remains false while awake.
1221     *
1222     * Whether mSleeping can quickly toggled between true/false without the device actually
1223     * display changing states is undefined.
1224     */
1225    private boolean mSleeping = false;
1226
1227    /**
1228     * The process state used for processes that are running the top activities.
1229     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1230     */
1231    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1232
1233    /**
1234     * Set while we are running a voice interaction.  This overrides
1235     * sleeping while it is active.
1236     */
1237    private IVoiceInteractionSession mRunningVoice;
1238
1239    /**
1240     * For some direct access we need to power manager.
1241     */
1242    PowerManagerInternal mLocalPowerManager;
1243
1244    /**
1245     * We want to hold a wake lock while running a voice interaction session, since
1246     * this may happen with the screen off and we need to keep the CPU running to
1247     * be able to continue to interact with the user.
1248     */
1249    PowerManager.WakeLock mVoiceWakeLock;
1250
1251    /**
1252     * State of external calls telling us if the device is awake or asleep.
1253     */
1254    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1255
1256    /**
1257     * A list of tokens that cause the top activity to be put to sleep.
1258     * They are used by components that may hide and block interaction with underlying
1259     * activities.
1260     */
1261    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1262
1263    static final int LOCK_SCREEN_HIDDEN = 0;
1264    static final int LOCK_SCREEN_LEAVING = 1;
1265    static final int LOCK_SCREEN_SHOWN = 2;
1266    /**
1267     * State of external call telling us if the lock screen is shown.
1268     */
1269    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1270
1271    /**
1272     * Set if we are shutting down the system, similar to sleeping.
1273     */
1274    boolean mShuttingDown = false;
1275
1276    /**
1277     * Current sequence id for oom_adj computation traversal.
1278     */
1279    int mAdjSeq = 0;
1280
1281    /**
1282     * Current sequence id for process LRU updating.
1283     */
1284    int mLruSeq = 0;
1285
1286    /**
1287     * Keep track of the non-cached/empty process we last found, to help
1288     * determine how to distribute cached/empty processes next time.
1289     */
1290    int mNumNonCachedProcs = 0;
1291
1292    /**
1293     * Keep track of the number of cached hidden procs, to balance oom adj
1294     * distribution between those and empty procs.
1295     */
1296    int mNumCachedHiddenProcs = 0;
1297
1298    /**
1299     * Keep track of the number of service processes we last found, to
1300     * determine on the next iteration which should be B services.
1301     */
1302    int mNumServiceProcs = 0;
1303    int mNewNumAServiceProcs = 0;
1304    int mNewNumServiceProcs = 0;
1305
1306    /**
1307     * Allow the current computed overall memory level of the system to go down?
1308     * This is set to false when we are killing processes for reasons other than
1309     * memory management, so that the now smaller process list will not be taken as
1310     * an indication that memory is tighter.
1311     */
1312    boolean mAllowLowerMemLevel = false;
1313
1314    /**
1315     * The last computed memory level, for holding when we are in a state that
1316     * processes are going away for other reasons.
1317     */
1318    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1319
1320    /**
1321     * The last total number of process we have, to determine if changes actually look
1322     * like a shrinking number of process due to lower RAM.
1323     */
1324    int mLastNumProcesses;
1325
1326    /**
1327     * The uptime of the last time we performed idle maintenance.
1328     */
1329    long mLastIdleTime = SystemClock.uptimeMillis();
1330
1331    /**
1332     * Total time spent with RAM that has been added in the past since the last idle time.
1333     */
1334    long mLowRamTimeSinceLastIdle = 0;
1335
1336    /**
1337     * If RAM is currently low, when that horrible situation started.
1338     */
1339    long mLowRamStartTime = 0;
1340
1341    /**
1342     * For reporting to battery stats the current top application.
1343     */
1344    private String mCurResumedPackage = null;
1345    private int mCurResumedUid = -1;
1346
1347    /**
1348     * For reporting to battery stats the apps currently running foreground
1349     * service.  The ProcessMap is package/uid tuples; each of these contain
1350     * an array of the currently foreground processes.
1351     */
1352    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1353            = new ProcessMap<ArrayList<ProcessRecord>>();
1354
1355    /**
1356     * This is set if we had to do a delayed dexopt of an app before launching
1357     * it, to increase the ANR timeouts in that case.
1358     */
1359    boolean mDidDexOpt;
1360
1361    /**
1362     * Set if the systemServer made a call to enterSafeMode.
1363     */
1364    boolean mSafeMode;
1365
1366    /**
1367     * If true, we are running under a test environment so will sample PSS from processes
1368     * much more rapidly to try to collect better data when the tests are rapidly
1369     * running through apps.
1370     */
1371    boolean mTestPssMode = false;
1372
1373    String mDebugApp = null;
1374    boolean mWaitForDebugger = false;
1375    boolean mDebugTransient = false;
1376    String mOrigDebugApp = null;
1377    boolean mOrigWaitForDebugger = false;
1378    boolean mAlwaysFinishActivities = false;
1379    boolean mLenientBackgroundCheck = false;
1380    boolean mForceResizableActivities;
1381    boolean mSupportsMultiWindow;
1382    boolean mSupportsFreeformWindowManagement;
1383    boolean mSupportsPictureInPicture;
1384    boolean mSupportsLeanbackOnly;
1385    Rect mDefaultPinnedStackBounds;
1386    IActivityController mController = null;
1387    boolean mControllerIsAMonkey = false;
1388    String mProfileApp = null;
1389    ProcessRecord mProfileProc = null;
1390    String mProfileFile;
1391    ParcelFileDescriptor mProfileFd;
1392    int mSamplingInterval = 0;
1393    boolean mAutoStopProfiler = false;
1394    int mProfileType = 0;
1395    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1396    String mMemWatchDumpProcName;
1397    String mMemWatchDumpFile;
1398    int mMemWatchDumpPid;
1399    int mMemWatchDumpUid;
1400    String mTrackAllocationApp = null;
1401    String mNativeDebuggingApp = null;
1402
1403    final long[] mTmpLong = new long[2];
1404
1405    static final class ProcessChangeItem {
1406        static final int CHANGE_ACTIVITIES = 1<<0;
1407        static final int CHANGE_PROCESS_STATE = 1<<1;
1408        int changes;
1409        int uid;
1410        int pid;
1411        int processState;
1412        boolean foregroundActivities;
1413    }
1414
1415    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1416    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1417
1418    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1419    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1420
1421    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1422    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1423
1424    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1425    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1426
1427    /**
1428     * Runtime CPU use collection thread.  This object's lock is used to
1429     * perform synchronization with the thread (notifying it to run).
1430     */
1431    final Thread mProcessCpuThread;
1432
1433    /**
1434     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1435     * Must acquire this object's lock when accessing it.
1436     * NOTE: this lock will be held while doing long operations (trawling
1437     * through all processes in /proc), so it should never be acquired by
1438     * any critical paths such as when holding the main activity manager lock.
1439     */
1440    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1441            MONITOR_THREAD_CPU_USAGE);
1442    final AtomicLong mLastCpuTime = new AtomicLong(0);
1443    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1444
1445    long mLastWriteTime = 0;
1446
1447    /**
1448     * Used to retain an update lock when the foreground activity is in
1449     * immersive mode.
1450     */
1451    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1452
1453    /**
1454     * Set to true after the system has finished booting.
1455     */
1456    boolean mBooted = false;
1457
1458    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1459    int mProcessLimitOverride = -1;
1460
1461    WindowManagerService mWindowManager;
1462    final ActivityThread mSystemThread;
1463
1464    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1465        final ProcessRecord mApp;
1466        final int mPid;
1467        final IApplicationThread mAppThread;
1468
1469        AppDeathRecipient(ProcessRecord app, int pid,
1470                IApplicationThread thread) {
1471            if (DEBUG_ALL) Slog.v(
1472                TAG, "New death recipient " + this
1473                + " for thread " + thread.asBinder());
1474            mApp = app;
1475            mPid = pid;
1476            mAppThread = thread;
1477        }
1478
1479        @Override
1480        public void binderDied() {
1481            if (DEBUG_ALL) Slog.v(
1482                TAG, "Death received in " + this
1483                + " for thread " + mAppThread.asBinder());
1484            synchronized(ActivityManagerService.this) {
1485                appDiedLocked(mApp, mPid, mAppThread, true);
1486            }
1487        }
1488    }
1489
1490    static final int SHOW_ERROR_UI_MSG = 1;
1491    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1492    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1493    static final int UPDATE_CONFIGURATION_MSG = 4;
1494    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1495    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1496    static final int SERVICE_TIMEOUT_MSG = 12;
1497    static final int UPDATE_TIME_ZONE = 13;
1498    static final int SHOW_UID_ERROR_UI_MSG = 14;
1499    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1500    static final int PROC_START_TIMEOUT_MSG = 20;
1501    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1502    static final int KILL_APPLICATION_MSG = 22;
1503    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1504    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1505    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1506    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1507    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1508    static final int CLEAR_DNS_CACHE_MSG = 28;
1509    static final int UPDATE_HTTP_PROXY_MSG = 29;
1510    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1511    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1512    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1513    static final int REPORT_MEM_USAGE_MSG = 33;
1514    static final int REPORT_USER_SWITCH_MSG = 34;
1515    static final int CONTINUE_USER_SWITCH_MSG = 35;
1516    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1517    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1518    static final int PERSIST_URI_GRANTS_MSG = 38;
1519    static final int REQUEST_ALL_PSS_MSG = 39;
1520    static final int START_PROFILES_MSG = 40;
1521    static final int UPDATE_TIME = 41;
1522    static final int SYSTEM_USER_START_MSG = 42;
1523    static final int SYSTEM_USER_CURRENT_MSG = 43;
1524    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1525    static final int FINISH_BOOTING_MSG = 45;
1526    static final int START_USER_SWITCH_UI_MSG = 46;
1527    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1528    static final int DISMISS_DIALOG_UI_MSG = 48;
1529    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1530    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1531    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1532    static final int DELETE_DUMPHEAP_MSG = 52;
1533    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1534    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1535    static final int REPORT_TIME_TRACKER_MSG = 55;
1536    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1537    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1538    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1539    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1540    static final int IDLE_UIDS_MSG = 60;
1541    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1542    static final int LOG_STACK_STATE = 62;
1543    static final int VR_MODE_CHANGE_MSG = 63;
1544    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1545    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1546    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1547    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1548    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1549    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
1550    static final int NOTIFY_VR_SLEEPING_MSG = 70;
1551
1552    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554    static final int FIRST_COMPAT_MODE_MSG = 300;
1555    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1556
1557    static ServiceThread sKillThread = null;
1558    static KillHandler sKillHandler = null;
1559
1560    CompatModeDialog mCompatModeDialog;
1561    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562    long mLastMemUsageReportTime = 0;
1563
1564    /**
1565     * Flag whether the current user is a "monkey", i.e. whether
1566     * the UI is driven by a UI automation tool.
1567     */
1568    private boolean mUserIsMonkey;
1569
1570    /** Flag whether the device has a Recents UI */
1571    boolean mHasRecents;
1572
1573    /** The dimensions of the thumbnails in the Recents UI. */
1574    int mThumbnailWidth;
1575    int mThumbnailHeight;
1576    float mFullscreenThumbnailScale;
1577
1578    final ServiceThread mHandlerThread;
1579    final MainHandler mHandler;
1580    final UiHandler mUiHandler;
1581
1582    PackageManagerInternal mPackageManagerInt;
1583
1584    // VoiceInteraction session ID that changes for each new request except when
1585    // being called for multiwindow assist in a single session.
1586    private int mViSessionId = 1000;
1587
1588    final boolean mPermissionReviewRequired;
1589
1590    final class KillHandler extends Handler {
1591        static final int KILL_PROCESS_GROUP_MSG = 4000;
1592
1593        public KillHandler(Looper looper) {
1594            super(looper, null, true);
1595        }
1596
1597        @Override
1598        public void handleMessage(Message msg) {
1599            switch (msg.what) {
1600                case KILL_PROCESS_GROUP_MSG:
1601                {
1602                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1605                }
1606                break;
1607
1608                default:
1609                    super.handleMessage(msg);
1610            }
1611        }
1612    }
1613
1614    final class UiHandler extends Handler {
1615        public UiHandler() {
1616            super(com.android.server.UiThread.get().getLooper(), null, true);
1617        }
1618
1619        @Override
1620        public void handleMessage(Message msg) {
1621            switch (msg.what) {
1622            case SHOW_ERROR_UI_MSG: {
1623                mAppErrors.handleShowAppErrorUi(msg);
1624                ensureBootCompleted();
1625            } break;
1626            case SHOW_NOT_RESPONDING_UI_MSG: {
1627                mAppErrors.handleShowAnrUi(msg);
1628                ensureBootCompleted();
1629            } break;
1630            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632                synchronized (ActivityManagerService.this) {
1633                    ProcessRecord proc = (ProcessRecord) data.get("app");
1634                    if (proc == null) {
1635                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1636                        break;
1637                    }
1638                    if (proc.crashDialog != null) {
1639                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1640                        return;
1641                    }
1642                    AppErrorResult res = (AppErrorResult) data.get("result");
1643                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644                        Dialog d = new StrictModeViolationDialog(mContext,
1645                                ActivityManagerService.this, res, proc);
1646                        d.show();
1647                        proc.crashDialog = d;
1648                    } else {
1649                        // The device is asleep, so just pretend that the user
1650                        // saw a crash dialog and hit "force quit".
1651                        res.set(0);
1652                    }
1653                }
1654                ensureBootCompleted();
1655            } break;
1656            case SHOW_FACTORY_ERROR_UI_MSG: {
1657                Dialog d = new FactoryErrorDialog(
1658                    mContext, msg.getData().getCharSequence("msg"));
1659                d.show();
1660                ensureBootCompleted();
1661            } break;
1662            case WAIT_FOR_DEBUGGER_UI_MSG: {
1663                synchronized (ActivityManagerService.this) {
1664                    ProcessRecord app = (ProcessRecord)msg.obj;
1665                    if (msg.arg1 != 0) {
1666                        if (!app.waitedForDebugger) {
1667                            Dialog d = new AppWaitingForDebuggerDialog(
1668                                    ActivityManagerService.this,
1669                                    mContext, app);
1670                            app.waitDialog = d;
1671                            app.waitedForDebugger = true;
1672                            d.show();
1673                        }
1674                    } else {
1675                        if (app.waitDialog != null) {
1676                            app.waitDialog.dismiss();
1677                            app.waitDialog = null;
1678                        }
1679                    }
1680                }
1681            } break;
1682            case SHOW_UID_ERROR_UI_MSG: {
1683                if (mShowDialogs) {
1684                    AlertDialog d = new BaseErrorDialog(mContext);
1685                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686                    d.setCancelable(false);
1687                    d.setTitle(mContext.getText(R.string.android_system_label));
1688                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1691                    d.show();
1692                }
1693            } break;
1694            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1695                if (mShowDialogs) {
1696                    AlertDialog d = new BaseErrorDialog(mContext);
1697                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698                    d.setCancelable(false);
1699                    d.setTitle(mContext.getText(R.string.android_system_label));
1700                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1703                    d.show();
1704                }
1705            } break;
1706            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    ActivityRecord ar = (ActivityRecord) msg.obj;
1709                    if (mCompatModeDialog != null) {
1710                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1711                                ar.info.applicationInfo.packageName)) {
1712                            return;
1713                        }
1714                        mCompatModeDialog.dismiss();
1715                        mCompatModeDialog = null;
1716                    }
1717                    if (ar != null && false) {
1718                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1719                                ar.packageName)) {
1720                            int mode = mCompatModePackages.computeCompatModeLocked(
1721                                    ar.info.applicationInfo);
1722                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724                                mCompatModeDialog = new CompatModeDialog(
1725                                        ActivityManagerService.this, mContext,
1726                                        ar.info.applicationInfo);
1727                                mCompatModeDialog.show();
1728                            }
1729                        }
1730                    }
1731                }
1732                break;
1733            }
1734            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1737                    if (mUnsupportedDisplaySizeDialog != null) {
1738                        mUnsupportedDisplaySizeDialog.dismiss();
1739                        mUnsupportedDisplaySizeDialog = null;
1740                    }
1741                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1742                            ar.packageName)) {
1743                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1744                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1745                        mUnsupportedDisplaySizeDialog.show();
1746                    }
1747                }
1748                break;
1749            }
1750            case START_USER_SWITCH_UI_MSG: {
1751                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1752                break;
1753            }
1754            case DISMISS_DIALOG_UI_MSG: {
1755                final Dialog d = (Dialog) msg.obj;
1756                d.dismiss();
1757                break;
1758            }
1759            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1760                dispatchProcessesChanged();
1761                break;
1762            }
1763            case DISPATCH_PROCESS_DIED_UI_MSG: {
1764                final int pid = msg.arg1;
1765                final int uid = msg.arg2;
1766                dispatchProcessDied(pid, uid);
1767                break;
1768            }
1769            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1770                dispatchUidsChanged();
1771            } break;
1772            }
1773        }
1774    }
1775
1776    final class MainHandler extends Handler {
1777        public MainHandler(Looper looper) {
1778            super(looper, null, true);
1779        }
1780
1781        @Override
1782        public void handleMessage(Message msg) {
1783            switch (msg.what) {
1784            case UPDATE_CONFIGURATION_MSG: {
1785                final ContentResolver resolver = mContext.getContentResolver();
1786                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1787                        msg.arg1);
1788            } break;
1789            case GC_BACKGROUND_PROCESSES_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    performAppGcsIfAppropriateLocked();
1792                }
1793            } break;
1794            case SERVICE_TIMEOUT_MSG: {
1795                if (mDidDexOpt) {
1796                    mDidDexOpt = false;
1797                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1798                    nmsg.obj = msg.obj;
1799                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1800                    return;
1801                }
1802                mServices.serviceTimeout((ProcessRecord)msg.obj);
1803            } break;
1804            case UPDATE_TIME_ZONE: {
1805                synchronized (ActivityManagerService.this) {
1806                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                        ProcessRecord r = mLruProcesses.get(i);
1808                        if (r.thread != null) {
1809                            try {
1810                                r.thread.updateTimeZone();
1811                            } catch (RemoteException ex) {
1812                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1813                            }
1814                        }
1815                    }
1816                }
1817            } break;
1818            case CLEAR_DNS_CACHE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821                        ProcessRecord r = mLruProcesses.get(i);
1822                        if (r.thread != null) {
1823                            try {
1824                                r.thread.clearDnsCache();
1825                            } catch (RemoteException ex) {
1826                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1827                            }
1828                        }
1829                    }
1830                }
1831            } break;
1832            case UPDATE_HTTP_PROXY_MSG: {
1833                ProxyInfo proxy = (ProxyInfo)msg.obj;
1834                String host = "";
1835                String port = "";
1836                String exclList = "";
1837                Uri pacFileUrl = Uri.EMPTY;
1838                if (proxy != null) {
1839                    host = proxy.getHost();
1840                    port = Integer.toString(proxy.getPort());
1841                    exclList = proxy.getExclusionListAsString();
1842                    pacFileUrl = proxy.getPacFileUrl();
1843                }
1844                synchronized (ActivityManagerService.this) {
1845                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846                        ProcessRecord r = mLruProcesses.get(i);
1847                        if (r.thread != null) {
1848                            try {
1849                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1850                            } catch (RemoteException ex) {
1851                                Slog.w(TAG, "Failed to update http proxy for: " +
1852                                        r.info.processName);
1853                            }
1854                        }
1855                    }
1856                }
1857            } break;
1858            case PROC_START_TIMEOUT_MSG: {
1859                if (mDidDexOpt) {
1860                    mDidDexOpt = false;
1861                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1862                    nmsg.obj = msg.obj;
1863                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1864                    return;
1865                }
1866                ProcessRecord app = (ProcessRecord)msg.obj;
1867                synchronized (ActivityManagerService.this) {
1868                    processStartTimedOutLocked(app);
1869                }
1870            } break;
1871            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1872                ProcessRecord app = (ProcessRecord)msg.obj;
1873                synchronized (ActivityManagerService.this) {
1874                    processContentProviderPublishTimedOutLocked(app);
1875                }
1876            } break;
1877            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1878                synchronized (ActivityManagerService.this) {
1879                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1880                }
1881            } break;
1882            case KILL_APPLICATION_MSG: {
1883                synchronized (ActivityManagerService.this) {
1884                    final int appId = msg.arg1;
1885                    final int userId = msg.arg2;
1886                    Bundle bundle = (Bundle)msg.obj;
1887                    String pkg = bundle.getString("pkg");
1888                    String reason = bundle.getString("reason");
1889                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1890                            false, userId, reason);
1891                }
1892            } break;
1893            case FINALIZE_PENDING_INTENT_MSG: {
1894                ((PendingIntentRecord)msg.obj).completeFinalize();
1895            } break;
1896            case POST_HEAVY_NOTIFICATION_MSG: {
1897                INotificationManager inm = NotificationManager.getService();
1898                if (inm == null) {
1899                    return;
1900                }
1901
1902                ActivityRecord root = (ActivityRecord)msg.obj;
1903                ProcessRecord process = root.app;
1904                if (process == null) {
1905                    return;
1906                }
1907
1908                try {
1909                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1910                    String text = mContext.getString(R.string.heavy_weight_notification,
1911                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1912                    Notification notification = new Notification.Builder(context)
1913                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1914                            .setWhen(0)
1915                            .setOngoing(true)
1916                            .setTicker(text)
1917                            .setColor(mContext.getColor(
1918                                    com.android.internal.R.color.system_notification_accent_color))
1919                            .setContentTitle(text)
1920                            .setContentText(
1921                                    mContext.getText(R.string.heavy_weight_notification_detail))
1922                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1923                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1924                                    new UserHandle(root.userId)))
1925                            .build();
1926                    try {
1927                        int[] outId = new int[1];
1928                        inm.enqueueNotificationWithTag("android", "android", null,
1929                                R.string.heavy_weight_notification,
1930                                notification, outId, root.userId);
1931                    } catch (RuntimeException e) {
1932                        Slog.w(ActivityManagerService.TAG,
1933                                "Error showing notification for heavy-weight app", e);
1934                    } catch (RemoteException e) {
1935                    }
1936                } catch (NameNotFoundException e) {
1937                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1938                }
1939            } break;
1940            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1941                INotificationManager inm = NotificationManager.getService();
1942                if (inm == null) {
1943                    return;
1944                }
1945                try {
1946                    inm.cancelNotificationWithTag("android", null,
1947                            R.string.heavy_weight_notification,  msg.arg1);
1948                } catch (RuntimeException e) {
1949                    Slog.w(ActivityManagerService.TAG,
1950                            "Error canceling notification for service", e);
1951                } catch (RemoteException e) {
1952                }
1953            } break;
1954            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    checkExcessivePowerUsageLocked(true);
1957                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1958                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1960                }
1961            } break;
1962            case REPORT_MEM_USAGE_MSG: {
1963                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1964                Thread thread = new Thread() {
1965                    @Override public void run() {
1966                        reportMemUsage(memInfos);
1967                    }
1968                };
1969                thread.start();
1970                break;
1971            }
1972            case REPORT_USER_SWITCH_MSG: {
1973                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1974                break;
1975            }
1976            case CONTINUE_USER_SWITCH_MSG: {
1977                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1978                break;
1979            }
1980            case USER_SWITCH_TIMEOUT_MSG: {
1981                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1982                break;
1983            }
1984            case IMMERSIVE_MODE_LOCK_MSG: {
1985                final boolean nextState = (msg.arg1 != 0);
1986                if (mUpdateLock.isHeld() != nextState) {
1987                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1988                            "Applying new update lock state '" + nextState
1989                            + "' for " + (ActivityRecord)msg.obj);
1990                    if (nextState) {
1991                        mUpdateLock.acquire();
1992                    } else {
1993                        mUpdateLock.release();
1994                    }
1995                }
1996                break;
1997            }
1998            case PERSIST_URI_GRANTS_MSG: {
1999                writeGrantedUriPermissions();
2000                break;
2001            }
2002            case REQUEST_ALL_PSS_MSG: {
2003                synchronized (ActivityManagerService.this) {
2004                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2005                }
2006                break;
2007            }
2008            case START_PROFILES_MSG: {
2009                synchronized (ActivityManagerService.this) {
2010                    mUserController.startProfilesLocked();
2011                }
2012                break;
2013            }
2014            case UPDATE_TIME: {
2015                synchronized (ActivityManagerService.this) {
2016                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2017                        ProcessRecord r = mLruProcesses.get(i);
2018                        if (r.thread != null) {
2019                            try {
2020                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2021                            } catch (RemoteException ex) {
2022                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2023                            }
2024                        }
2025                    }
2026                }
2027                break;
2028            }
2029            case SYSTEM_USER_START_MSG: {
2030                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2031                        Integer.toString(msg.arg1), msg.arg1);
2032                mSystemServiceManager.startUser(msg.arg1);
2033                break;
2034            }
2035            case SYSTEM_USER_UNLOCK_MSG: {
2036                final int userId = msg.arg1;
2037                mSystemServiceManager.unlockUser(userId);
2038                synchronized (ActivityManagerService.this) {
2039                    mRecentTasks.loadUserRecentsLocked(userId);
2040                }
2041                if (userId == UserHandle.USER_SYSTEM) {
2042                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2043                }
2044                installEncryptionUnawareProviders(userId);
2045                mUserController.finishUserUnlocked((UserState) msg.obj);
2046                break;
2047            }
2048            case SYSTEM_USER_CURRENT_MSG: {
2049                mBatteryStatsService.noteEvent(
2050                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2051                        Integer.toString(msg.arg2), msg.arg2);
2052                mBatteryStatsService.noteEvent(
2053                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2054                        Integer.toString(msg.arg1), msg.arg1);
2055                mSystemServiceManager.switchUser(msg.arg1);
2056                break;
2057            }
2058            case ENTER_ANIMATION_COMPLETE_MSG: {
2059                synchronized (ActivityManagerService.this) {
2060                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2061                    if (r != null && r.app != null && r.app.thread != null) {
2062                        try {
2063                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2064                        } catch (RemoteException e) {
2065                        }
2066                    }
2067                }
2068                break;
2069            }
2070            case FINISH_BOOTING_MSG: {
2071                if (msg.arg1 != 0) {
2072                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2073                    finishBooting();
2074                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2075                }
2076                if (msg.arg2 != 0) {
2077                    enableScreenAfterBoot();
2078                }
2079                break;
2080            }
2081            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2082                try {
2083                    Locale l = (Locale) msg.obj;
2084                    IBinder service = ServiceManager.getService("mount");
2085                    IMountService mountService = IMountService.Stub.asInterface(service);
2086                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2087                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2088                } catch (RemoteException e) {
2089                    Log.e(TAG, "Error storing locale for decryption UI", e);
2090                }
2091                break;
2092            }
2093            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2094                synchronized (ActivityManagerService.this) {
2095                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                        try {
2097                            // Make a one-way callback to the listener
2098                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2108                synchronized (ActivityManagerService.this) {
2109                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                        try {
2111                            // Make a one-way callback to the listener
2112                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2113                        } catch (RemoteException e){
2114                            // Handled by the RemoteCallbackList
2115                        }
2116                    }
2117                    mTaskStackListeners.finishBroadcast();
2118                }
2119                break;
2120            }
2121            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2122                synchronized (ActivityManagerService.this) {
2123                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                        try {
2125                            // Make a one-way callback to the listener
2126                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2136                synchronized (ActivityManagerService.this) {
2137                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                        try {
2139                            // Make a one-way callback to the listener
2140                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2141                        } catch (RemoteException e){
2142                            // Handled by the RemoteCallbackList
2143                        }
2144                    }
2145                    mTaskStackListeners.finishBroadcast();
2146                }
2147                break;
2148            }
2149            case NOTIFY_FORCED_RESIZABLE_MSG: {
2150                synchronized (ActivityManagerService.this) {
2151                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2152                        try {
2153                            // Make a one-way callback to the listener
2154                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2155                                    (String) msg.obj, msg.arg1);
2156                        } catch (RemoteException e){
2157                            // Handled by the RemoteCallbackList
2158                        }
2159                    }
2160                    mTaskStackListeners.finishBroadcast();
2161                }
2162                break;
2163            }
2164                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2165                    synchronized (ActivityManagerService.this) {
2166                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2167                            try {
2168                                // Make a one-way callback to the listener
2169                                mTaskStackListeners.getBroadcastItem(i)
2170                                        .onActivityDismissingDockedStack();
2171                            } catch (RemoteException e){
2172                                // Handled by the RemoteCallbackList
2173                            }
2174                        }
2175                        mTaskStackListeners.finishBroadcast();
2176                    }
2177                    break;
2178                }
2179            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2180                final int uid = msg.arg1;
2181                final byte[] firstPacket = (byte[]) msg.obj;
2182
2183                synchronized (mPidsSelfLocked) {
2184                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2185                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2186                        if (p.uid == uid) {
2187                            try {
2188                                p.thread.notifyCleartextNetwork(firstPacket);
2189                            } catch (RemoteException ignored) {
2190                            }
2191                        }
2192                    }
2193                }
2194                break;
2195            }
2196            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2197                final String procName;
2198                final int uid;
2199                final long memLimit;
2200                final String reportPackage;
2201                synchronized (ActivityManagerService.this) {
2202                    procName = mMemWatchDumpProcName;
2203                    uid = mMemWatchDumpUid;
2204                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2205                    if (val == null) {
2206                        val = mMemWatchProcesses.get(procName, 0);
2207                    }
2208                    if (val != null) {
2209                        memLimit = val.first;
2210                        reportPackage = val.second;
2211                    } else {
2212                        memLimit = 0;
2213                        reportPackage = null;
2214                    }
2215                }
2216                if (procName == null) {
2217                    return;
2218                }
2219
2220                if (DEBUG_PSS) Slog.d(TAG_PSS,
2221                        "Showing dump heap notification from " + procName + "/" + uid);
2222
2223                INotificationManager inm = NotificationManager.getService();
2224                if (inm == null) {
2225                    return;
2226                }
2227
2228                String text = mContext.getString(R.string.dump_heap_notification, procName);
2229
2230
2231                Intent deleteIntent = new Intent();
2232                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2233                Intent intent = new Intent();
2234                intent.setClassName("android", DumpHeapActivity.class.getName());
2235                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2236                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2237                if (reportPackage != null) {
2238                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2239                }
2240                int userId = UserHandle.getUserId(uid);
2241                Notification notification = new Notification.Builder(mContext)
2242                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2243                        .setWhen(0)
2244                        .setOngoing(true)
2245                        .setAutoCancel(true)
2246                        .setTicker(text)
2247                        .setColor(mContext.getColor(
2248                                com.android.internal.R.color.system_notification_accent_color))
2249                        .setContentTitle(text)
2250                        .setContentText(
2251                                mContext.getText(R.string.dump_heap_notification_detail))
2252                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2253                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2254                                new UserHandle(userId)))
2255                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2256                                deleteIntent, 0, UserHandle.SYSTEM))
2257                        .build();
2258
2259                try {
2260                    int[] outId = new int[1];
2261                    inm.enqueueNotificationWithTag("android", "android", null,
2262                            R.string.dump_heap_notification,
2263                            notification, outId, userId);
2264                } catch (RuntimeException e) {
2265                    Slog.w(ActivityManagerService.TAG,
2266                            "Error showing notification for dump heap", e);
2267                } catch (RemoteException e) {
2268                }
2269            } break;
2270            case DELETE_DUMPHEAP_MSG: {
2271                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2272                        DumpHeapActivity.JAVA_URI,
2273                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2274                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2275                        UserHandle.myUserId());
2276                synchronized (ActivityManagerService.this) {
2277                    mMemWatchDumpFile = null;
2278                    mMemWatchDumpProcName = null;
2279                    mMemWatchDumpPid = -1;
2280                    mMemWatchDumpUid = -1;
2281                }
2282            } break;
2283            case FOREGROUND_PROFILE_CHANGED_MSG: {
2284                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2285            } break;
2286            case REPORT_TIME_TRACKER_MSG: {
2287                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2288                tracker.deliverResult(mContext);
2289            } break;
2290            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2291                mUserController.dispatchUserSwitchComplete(msg.arg1);
2292            } break;
2293            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2294                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2295                try {
2296                    connection.shutdown();
2297                } catch (RemoteException e) {
2298                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2299                }
2300                // Only a UiAutomation can set this flag and now that
2301                // it is finished we make sure it is reset to its default.
2302                mUserIsMonkey = false;
2303            } break;
2304            case APP_BOOST_DEACTIVATE_MSG: {
2305                synchronized(ActivityManagerService.this) {
2306                    if (mIsBoosted) {
2307                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2308                            nativeMigrateFromBoost();
2309                            mIsBoosted = false;
2310                            mBoostStartTime = 0;
2311                        } else {
2312                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2313                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2314                        }
2315                    }
2316                }
2317            } break;
2318            case IDLE_UIDS_MSG: {
2319                idleUids();
2320            } break;
2321            case LOG_STACK_STATE: {
2322                synchronized (ActivityManagerService.this) {
2323                    mStackSupervisor.logStackState();
2324                }
2325            } break;
2326            case VR_MODE_CHANGE_MSG: {
2327                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2328                if (vrService == null) {
2329                    break;
2330                }
2331                final ActivityRecord r = (ActivityRecord) msg.obj;
2332                boolean vrMode;
2333                ComponentName requestedPackage;
2334                ComponentName callingPackage;
2335                int userId;
2336                synchronized (ActivityManagerService.this) {
2337                    vrMode = r.requestedVrComponent != null;
2338                    requestedPackage = r.requestedVrComponent;
2339                    userId = r.userId;
2340                    callingPackage = r.info.getComponentName();
2341                    if (mInVrMode != vrMode) {
2342                        mInVrMode = vrMode;
2343                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2344                        if (r.app != null) {
2345                            ProcessRecord proc = r.app;
2346                            if (proc.vrThreadTid > 0) {
2347                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2348                                    try {
2349                                        if (mInVrMode == true) {
2350                                            Process.setThreadScheduler(proc.vrThreadTid,
2351                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2352                                        } else {
2353                                            Process.setThreadScheduler(proc.vrThreadTid,
2354                                                Process.SCHED_OTHER, 0);
2355                                        }
2356                                    } catch (IllegalArgumentException e) {
2357                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2358                                                + " not exist:\n" + e);
2359                                    }
2360                                }
2361                            }
2362                        }
2363                    }
2364                }
2365                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2366            } case NOTIFY_VR_SLEEPING_MSG: {
2367                notifyVrManagerOfSleepState(msg.arg1 != 0);
2368            } break;
2369            }
2370        }
2371    };
2372
2373    static final int COLLECT_PSS_BG_MSG = 1;
2374
2375    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2376        @Override
2377        public void handleMessage(Message msg) {
2378            switch (msg.what) {
2379            case COLLECT_PSS_BG_MSG: {
2380                long start = SystemClock.uptimeMillis();
2381                MemInfoReader memInfo = null;
2382                synchronized (ActivityManagerService.this) {
2383                    if (mFullPssPending) {
2384                        mFullPssPending = false;
2385                        memInfo = new MemInfoReader();
2386                    }
2387                }
2388                if (memInfo != null) {
2389                    updateCpuStatsNow();
2390                    long nativeTotalPss = 0;
2391                    final List<ProcessCpuTracker.Stats> stats;
2392                    synchronized (mProcessCpuTracker) {
2393                        stats = mProcessCpuTracker.getStats( (st)-> {
2394                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2395                        });
2396                    }
2397                    final int N = stats.size();
2398                    for (int j = 0; j < N; j++) {
2399                        synchronized (mPidsSelfLocked) {
2400                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2401                                // This is one of our own processes; skip it.
2402                                continue;
2403                            }
2404                        }
2405                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2406                    }
2407                    memInfo.readMemInfo();
2408                    synchronized (ActivityManagerService.this) {
2409                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2410                                + (SystemClock.uptimeMillis()-start) + "ms");
2411                        final long cachedKb = memInfo.getCachedSizeKb();
2412                        final long freeKb = memInfo.getFreeSizeKb();
2413                        final long zramKb = memInfo.getZramTotalSizeKb();
2414                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2415                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2416                                kernelKb*1024, nativeTotalPss*1024);
2417                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2418                                nativeTotalPss);
2419                    }
2420                }
2421
2422                int num = 0;
2423                long[] tmp = new long[2];
2424                do {
2425                    ProcessRecord proc;
2426                    int procState;
2427                    int pid;
2428                    long lastPssTime;
2429                    synchronized (ActivityManagerService.this) {
2430                        if (mPendingPssProcesses.size() <= 0) {
2431                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2432                                    "Collected PSS of " + num + " processes in "
2433                                    + (SystemClock.uptimeMillis() - start) + "ms");
2434                            mPendingPssProcesses.clear();
2435                            return;
2436                        }
2437                        proc = mPendingPssProcesses.remove(0);
2438                        procState = proc.pssProcState;
2439                        lastPssTime = proc.lastPssTime;
2440                        if (proc.thread != null && procState == proc.setProcState
2441                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2442                                        < SystemClock.uptimeMillis()) {
2443                            pid = proc.pid;
2444                        } else {
2445                            proc = null;
2446                            pid = 0;
2447                        }
2448                    }
2449                    if (proc != null) {
2450                        long pss = Debug.getPss(pid, tmp, null);
2451                        synchronized (ActivityManagerService.this) {
2452                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2453                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2454                                num++;
2455                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2456                                        SystemClock.uptimeMillis());
2457                            }
2458                        }
2459                    }
2460                } while (true);
2461            }
2462            }
2463        }
2464    };
2465
2466    public void setSystemProcess() {
2467        try {
2468            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2469            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2470            ServiceManager.addService("meminfo", new MemBinder(this));
2471            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2472            ServiceManager.addService("dbinfo", new DbBinder(this));
2473            if (MONITOR_CPU_USAGE) {
2474                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2475            }
2476            ServiceManager.addService("permission", new PermissionController(this));
2477            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2478
2479            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2480                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2481            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2482
2483            synchronized (this) {
2484                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2485                app.persistent = true;
2486                app.pid = MY_PID;
2487                app.maxAdj = ProcessList.SYSTEM_ADJ;
2488                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2489                synchronized (mPidsSelfLocked) {
2490                    mPidsSelfLocked.put(app.pid, app);
2491                }
2492                updateLruProcessLocked(app, false, null);
2493                updateOomAdjLocked();
2494            }
2495        } catch (PackageManager.NameNotFoundException e) {
2496            throw new RuntimeException(
2497                    "Unable to find android system package", e);
2498        }
2499    }
2500
2501    public void setWindowManager(WindowManagerService wm) {
2502        mWindowManager = wm;
2503        mStackSupervisor.setWindowManager(wm);
2504        mActivityStarter.setWindowManager(wm);
2505    }
2506
2507    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2508        mUsageStatsService = usageStatsManager;
2509    }
2510
2511    public void startObservingNativeCrashes() {
2512        final NativeCrashListener ncl = new NativeCrashListener(this);
2513        ncl.start();
2514    }
2515
2516    public IAppOpsService getAppOpsService() {
2517        return mAppOpsService;
2518    }
2519
2520    static class MemBinder extends Binder {
2521        ActivityManagerService mActivityManagerService;
2522        MemBinder(ActivityManagerService activityManagerService) {
2523            mActivityManagerService = activityManagerService;
2524        }
2525
2526        @Override
2527        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2528            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2529                    != PackageManager.PERMISSION_GRANTED) {
2530                pw.println("Permission Denial: can't dump meminfo from from pid="
2531                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2532                        + " without permission " + android.Manifest.permission.DUMP);
2533                return;
2534            }
2535
2536            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2537        }
2538    }
2539
2540    static class GraphicsBinder extends Binder {
2541        ActivityManagerService mActivityManagerService;
2542        GraphicsBinder(ActivityManagerService activityManagerService) {
2543            mActivityManagerService = activityManagerService;
2544        }
2545
2546        @Override
2547        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2548            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2549                    != PackageManager.PERMISSION_GRANTED) {
2550                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2551                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2552                        + " without permission " + android.Manifest.permission.DUMP);
2553                return;
2554            }
2555
2556            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2557        }
2558    }
2559
2560    static class DbBinder extends Binder {
2561        ActivityManagerService mActivityManagerService;
2562        DbBinder(ActivityManagerService activityManagerService) {
2563            mActivityManagerService = activityManagerService;
2564        }
2565
2566        @Override
2567        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2568            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2569                    != PackageManager.PERMISSION_GRANTED) {
2570                pw.println("Permission Denial: can't dump dbinfo from from pid="
2571                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2572                        + " without permission " + android.Manifest.permission.DUMP);
2573                return;
2574            }
2575
2576            mActivityManagerService.dumpDbInfo(fd, pw, args);
2577        }
2578    }
2579
2580    static class CpuBinder extends Binder {
2581        ActivityManagerService mActivityManagerService;
2582        CpuBinder(ActivityManagerService activityManagerService) {
2583            mActivityManagerService = activityManagerService;
2584        }
2585
2586        @Override
2587        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2588            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2589                    != PackageManager.PERMISSION_GRANTED) {
2590                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2591                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2592                        + " without permission " + android.Manifest.permission.DUMP);
2593                return;
2594            }
2595
2596            synchronized (mActivityManagerService.mProcessCpuTracker) {
2597                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2598                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2599                        SystemClock.uptimeMillis()));
2600            }
2601        }
2602    }
2603
2604    public static final class Lifecycle extends SystemService {
2605        private final ActivityManagerService mService;
2606
2607        public Lifecycle(Context context) {
2608            super(context);
2609            mService = new ActivityManagerService(context);
2610        }
2611
2612        @Override
2613        public void onStart() {
2614            mService.start();
2615        }
2616
2617        public ActivityManagerService getService() {
2618            return mService;
2619        }
2620    }
2621
2622    // Note: This method is invoked on the main thread but may need to attach various
2623    // handlers to other threads.  So take care to be explicit about the looper.
2624    public ActivityManagerService(Context systemContext) {
2625        mContext = systemContext;
2626        mFactoryTest = FactoryTest.getMode();
2627        mSystemThread = ActivityThread.currentActivityThread();
2628
2629        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2630
2631        mPermissionReviewRequired = mContext.getResources().getBoolean(
2632                com.android.internal.R.bool.config_permissionReviewRequired);
2633
2634        mHandlerThread = new ServiceThread(TAG,
2635                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2636        mHandlerThread.start();
2637        mHandler = new MainHandler(mHandlerThread.getLooper());
2638        mUiHandler = new UiHandler();
2639
2640        /* static; one-time init here */
2641        if (sKillHandler == null) {
2642            sKillThread = new ServiceThread(TAG + ":kill",
2643                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2644            sKillThread.start();
2645            sKillHandler = new KillHandler(sKillThread.getLooper());
2646        }
2647
2648        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2649                "foreground", BROADCAST_FG_TIMEOUT, false);
2650        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2651                "background", BROADCAST_BG_TIMEOUT, true);
2652        mBroadcastQueues[0] = mFgBroadcastQueue;
2653        mBroadcastQueues[1] = mBgBroadcastQueue;
2654
2655        mServices = new ActiveServices(this);
2656        mProviderMap = new ProviderMap(this);
2657        mAppErrors = new AppErrors(mContext, this);
2658
2659        // TODO: Move creation of battery stats service outside of activity manager service.
2660        File dataDir = Environment.getDataDirectory();
2661        File systemDir = new File(dataDir, "system");
2662        systemDir.mkdirs();
2663        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2664        mBatteryStatsService.getActiveStatistics().readLocked();
2665        mBatteryStatsService.scheduleWriteToDisk();
2666        mOnBattery = DEBUG_POWER ? true
2667                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2668        mBatteryStatsService.getActiveStatistics().setCallback(this);
2669
2670        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2671
2672        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2673        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2674                new IAppOpsCallback.Stub() {
2675                    @Override public void opChanged(int op, int uid, String packageName) {
2676                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2677                            if (mAppOpsService.checkOperation(op, uid, packageName)
2678                                    != AppOpsManager.MODE_ALLOWED) {
2679                                runInBackgroundDisabled(uid);
2680                            }
2681                        }
2682                    }
2683                });
2684
2685        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2686
2687        mUserController = new UserController(this);
2688
2689        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2690            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2691
2692        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2693            mUseFifoUiScheduling = true;
2694        }
2695
2696        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2697
2698        mConfiguration.setToDefaults();
2699        mConfiguration.setLocales(LocaleList.getDefault());
2700
2701        mConfigurationSeq = mConfiguration.seq = 1;
2702        mProcessCpuTracker.init();
2703
2704        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2705        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2706        mStackSupervisor = new ActivityStackSupervisor(this);
2707        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2708        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2709
2710        mProcessCpuThread = new Thread("CpuTracker") {
2711            @Override
2712            public void run() {
2713                while (true) {
2714                    try {
2715                        try {
2716                            synchronized(this) {
2717                                final long now = SystemClock.uptimeMillis();
2718                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2719                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2720                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2721                                //        + ", write delay=" + nextWriteDelay);
2722                                if (nextWriteDelay < nextCpuDelay) {
2723                                    nextCpuDelay = nextWriteDelay;
2724                                }
2725                                if (nextCpuDelay > 0) {
2726                                    mProcessCpuMutexFree.set(true);
2727                                    this.wait(nextCpuDelay);
2728                                }
2729                            }
2730                        } catch (InterruptedException e) {
2731                        }
2732                        updateCpuStatsNow();
2733                    } catch (Exception e) {
2734                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2735                    }
2736                }
2737            }
2738        };
2739
2740        Watchdog.getInstance().addMonitor(this);
2741        Watchdog.getInstance().addThread(mHandler);
2742    }
2743
2744    public void setSystemServiceManager(SystemServiceManager mgr) {
2745        mSystemServiceManager = mgr;
2746    }
2747
2748    public void setInstaller(Installer installer) {
2749        mInstaller = installer;
2750    }
2751
2752    private void start() {
2753        Process.removeAllProcessGroups();
2754        mProcessCpuThread.start();
2755
2756        mBatteryStatsService.publish(mContext);
2757        mAppOpsService.publish(mContext);
2758        Slog.d("AppOps", "AppOpsService published");
2759        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2760    }
2761
2762    void onUserStoppedLocked(int userId) {
2763        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2764    }
2765
2766    public void initPowerManagement() {
2767        mStackSupervisor.initPowerManagement();
2768        mBatteryStatsService.initPowerManagement();
2769        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2770        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2771        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2772        mVoiceWakeLock.setReferenceCounted(false);
2773    }
2774
2775    @Override
2776    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2777            throws RemoteException {
2778        if (code == SYSPROPS_TRANSACTION) {
2779            // We need to tell all apps about the system property change.
2780            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2781            synchronized(this) {
2782                final int NP = mProcessNames.getMap().size();
2783                for (int ip=0; ip<NP; ip++) {
2784                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2785                    final int NA = apps.size();
2786                    for (int ia=0; ia<NA; ia++) {
2787                        ProcessRecord app = apps.valueAt(ia);
2788                        if (app.thread != null) {
2789                            procs.add(app.thread.asBinder());
2790                        }
2791                    }
2792                }
2793            }
2794
2795            int N = procs.size();
2796            for (int i=0; i<N; i++) {
2797                Parcel data2 = Parcel.obtain();
2798                try {
2799                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2800                } catch (RemoteException e) {
2801                }
2802                data2.recycle();
2803            }
2804        }
2805        try {
2806            return super.onTransact(code, data, reply, flags);
2807        } catch (RuntimeException e) {
2808            // The activity manager only throws security exceptions, so let's
2809            // log all others.
2810            if (!(e instanceof SecurityException)) {
2811                Slog.wtf(TAG, "Activity Manager Crash", e);
2812            }
2813            throw e;
2814        }
2815    }
2816
2817    void updateCpuStats() {
2818        final long now = SystemClock.uptimeMillis();
2819        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2820            return;
2821        }
2822        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2823            synchronized (mProcessCpuThread) {
2824                mProcessCpuThread.notify();
2825            }
2826        }
2827    }
2828
2829    void updateCpuStatsNow() {
2830        synchronized (mProcessCpuTracker) {
2831            mProcessCpuMutexFree.set(false);
2832            final long now = SystemClock.uptimeMillis();
2833            boolean haveNewCpuStats = false;
2834
2835            if (MONITOR_CPU_USAGE &&
2836                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2837                mLastCpuTime.set(now);
2838                mProcessCpuTracker.update();
2839                if (mProcessCpuTracker.hasGoodLastStats()) {
2840                    haveNewCpuStats = true;
2841                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2842                    //Slog.i(TAG, "Total CPU usage: "
2843                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2844
2845                    // Slog the cpu usage if the property is set.
2846                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2847                        int user = mProcessCpuTracker.getLastUserTime();
2848                        int system = mProcessCpuTracker.getLastSystemTime();
2849                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2850                        int irq = mProcessCpuTracker.getLastIrqTime();
2851                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2852                        int idle = mProcessCpuTracker.getLastIdleTime();
2853
2854                        int total = user + system + iowait + irq + softIrq + idle;
2855                        if (total == 0) total = 1;
2856
2857                        EventLog.writeEvent(EventLogTags.CPU,
2858                                ((user+system+iowait+irq+softIrq) * 100) / total,
2859                                (user * 100) / total,
2860                                (system * 100) / total,
2861                                (iowait * 100) / total,
2862                                (irq * 100) / total,
2863                                (softIrq * 100) / total);
2864                    }
2865                }
2866            }
2867
2868            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2869            synchronized(bstats) {
2870                synchronized(mPidsSelfLocked) {
2871                    if (haveNewCpuStats) {
2872                        if (bstats.startAddingCpuLocked()) {
2873                            int totalUTime = 0;
2874                            int totalSTime = 0;
2875                            final int N = mProcessCpuTracker.countStats();
2876                            for (int i=0; i<N; i++) {
2877                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2878                                if (!st.working) {
2879                                    continue;
2880                                }
2881                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2882                                totalUTime += st.rel_utime;
2883                                totalSTime += st.rel_stime;
2884                                if (pr != null) {
2885                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2886                                    if (ps == null || !ps.isActive()) {
2887                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2888                                                pr.info.uid, pr.processName);
2889                                    }
2890                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2891                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2892                                } else {
2893                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2894                                    if (ps == null || !ps.isActive()) {
2895                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2896                                                bstats.mapUid(st.uid), st.name);
2897                                    }
2898                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2899                                }
2900                            }
2901                            final int userTime = mProcessCpuTracker.getLastUserTime();
2902                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2903                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2904                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2905                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2906                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2907                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2908                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2909                        }
2910                    }
2911                }
2912
2913                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2914                    mLastWriteTime = now;
2915                    mBatteryStatsService.scheduleWriteToDisk();
2916                }
2917            }
2918        }
2919    }
2920
2921    @Override
2922    public void batteryNeedsCpuUpdate() {
2923        updateCpuStatsNow();
2924    }
2925
2926    @Override
2927    public void batteryPowerChanged(boolean onBattery) {
2928        // When plugging in, update the CPU stats first before changing
2929        // the plug state.
2930        updateCpuStatsNow();
2931        synchronized (this) {
2932            synchronized(mPidsSelfLocked) {
2933                mOnBattery = DEBUG_POWER ? true : onBattery;
2934            }
2935        }
2936    }
2937
2938    @Override
2939    public void batterySendBroadcast(Intent intent) {
2940        synchronized (this) {
2941            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2942                    AppOpsManager.OP_NONE, null, false, false,
2943                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2944        }
2945    }
2946
2947    /**
2948     * Initialize the application bind args. These are passed to each
2949     * process when the bindApplication() IPC is sent to the process. They're
2950     * lazily setup to make sure the services are running when they're asked for.
2951     */
2952    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2953        // Isolated processes won't get this optimization, so that we don't
2954        // violate the rules about which services they have access to.
2955        if (isolated) {
2956            if (mIsolatedAppBindArgs == null) {
2957                mIsolatedAppBindArgs = new HashMap<>();
2958                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2959            }
2960            return mIsolatedAppBindArgs;
2961        }
2962
2963        if (mAppBindArgs == null) {
2964            mAppBindArgs = new HashMap<>();
2965
2966            // Setup the application init args
2967            mAppBindArgs.put("package", ServiceManager.getService("package"));
2968            mAppBindArgs.put("window", ServiceManager.getService("window"));
2969            mAppBindArgs.put(Context.ALARM_SERVICE,
2970                    ServiceManager.getService(Context.ALARM_SERVICE));
2971        }
2972        return mAppBindArgs;
2973    }
2974
2975    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2976        if (r == null || mFocusedActivity == r) {
2977            return false;
2978        }
2979
2980        if (!r.isFocusable()) {
2981            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2982            return false;
2983        }
2984
2985        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2986
2987        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2988        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2989                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2990        mDoingSetFocusedActivity = true;
2991
2992        final ActivityRecord last = mFocusedActivity;
2993        mFocusedActivity = r;
2994        if (r.task.isApplicationTask()) {
2995            if (mCurAppTimeTracker != r.appTimeTracker) {
2996                // We are switching app tracking.  Complete the current one.
2997                if (mCurAppTimeTracker != null) {
2998                    mCurAppTimeTracker.stop();
2999                    mHandler.obtainMessage(
3000                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3001                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3002                    mCurAppTimeTracker = null;
3003                }
3004                if (r.appTimeTracker != null) {
3005                    mCurAppTimeTracker = r.appTimeTracker;
3006                    startTimeTrackingFocusedActivityLocked();
3007                }
3008            } else {
3009                startTimeTrackingFocusedActivityLocked();
3010            }
3011        } else {
3012            r.appTimeTracker = null;
3013        }
3014        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3015        // TODO: Probably not, because we don't want to resume voice on switching
3016        // back to this activity
3017        if (r.task.voiceInteractor != null) {
3018            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3019        } else {
3020            finishRunningVoiceLocked();
3021            IVoiceInteractionSession session;
3022            if (last != null && ((session = last.task.voiceSession) != null
3023                    || (session = last.voiceSession) != null)) {
3024                // We had been in a voice interaction session, but now focused has
3025                // move to something different.  Just finish the session, we can't
3026                // return to it and retain the proper state and synchronization with
3027                // the voice interaction service.
3028                finishVoiceTask(session);
3029            }
3030        }
3031        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3032            mWindowManager.setFocusedApp(r.appToken, true);
3033        }
3034        applyUpdateLockStateLocked(r);
3035        applyUpdateVrModeLocked(r);
3036        if (mFocusedActivity.userId != mLastFocusedUserId) {
3037            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3038            mHandler.obtainMessage(
3039                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3040            mLastFocusedUserId = mFocusedActivity.userId;
3041        }
3042
3043        // Log a warning if the focused app is changed during the process. This could
3044        // indicate a problem of the focus setting logic!
3045        if (mFocusedActivity != r) Slog.w(TAG,
3046                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3047        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3048
3049        EventLogTags.writeAmFocusedActivity(
3050                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3051                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3052                reason);
3053        return true;
3054    }
3055
3056    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3057        if (mFocusedActivity != goingAway) {
3058            return;
3059        }
3060
3061        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3062        if (focusedStack != null) {
3063            final ActivityRecord top = focusedStack.topActivity();
3064            if (top != null && top.userId != mLastFocusedUserId) {
3065                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3066                mHandler.sendMessage(
3067                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3068                mLastFocusedUserId = top.userId;
3069            }
3070        }
3071
3072        // Try to move focus to another activity if possible.
3073        if (setFocusedActivityLocked(
3074                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3075            return;
3076        }
3077
3078        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3079                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3080        mFocusedActivity = null;
3081        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3082    }
3083
3084    @Override
3085    public void setFocusedStack(int stackId) {
3086        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3087        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3088        final long callingId = Binder.clearCallingIdentity();
3089        try {
3090            synchronized (this) {
3091                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3092                if (stack == null) {
3093                    return;
3094                }
3095                final ActivityRecord r = stack.topRunningActivityLocked();
3096                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3097                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3098                }
3099            }
3100        } finally {
3101            Binder.restoreCallingIdentity(callingId);
3102        }
3103    }
3104
3105    @Override
3106    public void setFocusedTask(int taskId) {
3107        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3108        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3109        final long callingId = Binder.clearCallingIdentity();
3110        try {
3111            synchronized (this) {
3112                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3113                if (task == null) {
3114                    return;
3115                }
3116                if (mUserController.shouldConfirmCredentials(task.userId)) {
3117                    mActivityStarter.showConfirmDeviceCredential(task.userId);
3118                    if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3119                        mStackSupervisor.moveTaskToStackLocked(task.taskId,
3120                                FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3121                                "setFocusedTask", ANIMATE);
3122                    }
3123                    return;
3124                }
3125                final ActivityRecord r = task.topRunningActivityLocked();
3126                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3127                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3128                }
3129            }
3130        } finally {
3131            Binder.restoreCallingIdentity(callingId);
3132        }
3133    }
3134
3135    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3136    @Override
3137    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3138        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3139        synchronized (this) {
3140            if (listener != null) {
3141                mTaskStackListeners.register(listener);
3142            }
3143        }
3144    }
3145
3146    @Override
3147    public void notifyActivityDrawn(IBinder token) {
3148        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3149        synchronized (this) {
3150            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3151            if (r != null) {
3152                r.task.stack.notifyActivityDrawnLocked(r);
3153            }
3154        }
3155    }
3156
3157    final void applyUpdateLockStateLocked(ActivityRecord r) {
3158        // Modifications to the UpdateLock state are done on our handler, outside
3159        // the activity manager's locks.  The new state is determined based on the
3160        // state *now* of the relevant activity record.  The object is passed to
3161        // the handler solely for logging detail, not to be consulted/modified.
3162        final boolean nextState = r != null && r.immersive;
3163        mHandler.sendMessage(
3164                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3165    }
3166
3167    final void applyUpdateVrModeLocked(ActivityRecord r) {
3168        mHandler.sendMessage(
3169                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3170    }
3171
3172    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3173        mHandler.sendMessage(
3174                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3175    }
3176
3177    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3178        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3179        if (vrService == null) {
3180            return;
3181        }
3182        vrService.onSleepStateChanged(isSleeping);
3183    }
3184
3185    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3186        Message msg = Message.obtain();
3187        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3188        msg.obj = r.task.askedCompatMode ? null : r;
3189        mUiHandler.sendMessage(msg);
3190    }
3191
3192    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3193        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3194                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3195            final Message msg = Message.obtain();
3196            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3197            msg.obj = r;
3198            mUiHandler.sendMessage(msg);
3199        }
3200    }
3201
3202    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3203            String what, Object obj, ProcessRecord srcApp) {
3204        app.lastActivityTime = now;
3205
3206        if (app.activities.size() > 0) {
3207            // Don't want to touch dependent processes that are hosting activities.
3208            return index;
3209        }
3210
3211        int lrui = mLruProcesses.lastIndexOf(app);
3212        if (lrui < 0) {
3213            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3214                    + what + " " + obj + " from " + srcApp);
3215            return index;
3216        }
3217
3218        if (lrui >= index) {
3219            // Don't want to cause this to move dependent processes *back* in the
3220            // list as if they were less frequently used.
3221            return index;
3222        }
3223
3224        if (lrui >= mLruProcessActivityStart) {
3225            // Don't want to touch dependent processes that are hosting activities.
3226            return index;
3227        }
3228
3229        mLruProcesses.remove(lrui);
3230        if (index > 0) {
3231            index--;
3232        }
3233        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3234                + " in LRU list: " + app);
3235        mLruProcesses.add(index, app);
3236        return index;
3237    }
3238
3239    static void killProcessGroup(int uid, int pid) {
3240        if (sKillHandler != null) {
3241            sKillHandler.sendMessage(
3242                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3243        } else {
3244            Slog.w(TAG, "Asked to kill process group before system bringup!");
3245            Process.killProcessGroup(uid, pid);
3246        }
3247    }
3248
3249    final void removeLruProcessLocked(ProcessRecord app) {
3250        int lrui = mLruProcesses.lastIndexOf(app);
3251        if (lrui >= 0) {
3252            if (!app.killed) {
3253                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3254                Process.killProcessQuiet(app.pid);
3255                killProcessGroup(app.uid, app.pid);
3256            }
3257            if (lrui <= mLruProcessActivityStart) {
3258                mLruProcessActivityStart--;
3259            }
3260            if (lrui <= mLruProcessServiceStart) {
3261                mLruProcessServiceStart--;
3262            }
3263            mLruProcesses.remove(lrui);
3264        }
3265    }
3266
3267    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3268            ProcessRecord client) {
3269        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3270                || app.treatLikeActivity;
3271        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3272        if (!activityChange && hasActivity) {
3273            // The process has activities, so we are only allowing activity-based adjustments
3274            // to move it.  It should be kept in the front of the list with other
3275            // processes that have activities, and we don't want those to change their
3276            // order except due to activity operations.
3277            return;
3278        }
3279
3280        mLruSeq++;
3281        final long now = SystemClock.uptimeMillis();
3282        app.lastActivityTime = now;
3283
3284        // First a quick reject: if the app is already at the position we will
3285        // put it, then there is nothing to do.
3286        if (hasActivity) {
3287            final int N = mLruProcesses.size();
3288            if (N > 0 && mLruProcesses.get(N-1) == app) {
3289                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3290                return;
3291            }
3292        } else {
3293            if (mLruProcessServiceStart > 0
3294                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3295                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3296                return;
3297            }
3298        }
3299
3300        int lrui = mLruProcesses.lastIndexOf(app);
3301
3302        if (app.persistent && lrui >= 0) {
3303            // We don't care about the position of persistent processes, as long as
3304            // they are in the list.
3305            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3306            return;
3307        }
3308
3309        /* In progress: compute new position first, so we can avoid doing work
3310           if the process is not actually going to move.  Not yet working.
3311        int addIndex;
3312        int nextIndex;
3313        boolean inActivity = false, inService = false;
3314        if (hasActivity) {
3315            // Process has activities, put it at the very tipsy-top.
3316            addIndex = mLruProcesses.size();
3317            nextIndex = mLruProcessServiceStart;
3318            inActivity = true;
3319        } else if (hasService) {
3320            // Process has services, put it at the top of the service list.
3321            addIndex = mLruProcessActivityStart;
3322            nextIndex = mLruProcessServiceStart;
3323            inActivity = true;
3324            inService = true;
3325        } else  {
3326            // Process not otherwise of interest, it goes to the top of the non-service area.
3327            addIndex = mLruProcessServiceStart;
3328            if (client != null) {
3329                int clientIndex = mLruProcesses.lastIndexOf(client);
3330                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3331                        + app);
3332                if (clientIndex >= 0 && addIndex > clientIndex) {
3333                    addIndex = clientIndex;
3334                }
3335            }
3336            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3337        }
3338
3339        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3340                + mLruProcessActivityStart + "): " + app);
3341        */
3342
3343        if (lrui >= 0) {
3344            if (lrui < mLruProcessActivityStart) {
3345                mLruProcessActivityStart--;
3346            }
3347            if (lrui < mLruProcessServiceStart) {
3348                mLruProcessServiceStart--;
3349            }
3350            /*
3351            if (addIndex > lrui) {
3352                addIndex--;
3353            }
3354            if (nextIndex > lrui) {
3355                nextIndex--;
3356            }
3357            */
3358            mLruProcesses.remove(lrui);
3359        }
3360
3361        /*
3362        mLruProcesses.add(addIndex, app);
3363        if (inActivity) {
3364            mLruProcessActivityStart++;
3365        }
3366        if (inService) {
3367            mLruProcessActivityStart++;
3368        }
3369        */
3370
3371        int nextIndex;
3372        if (hasActivity) {
3373            final int N = mLruProcesses.size();
3374            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3375                // Process doesn't have activities, but has clients with
3376                // activities...  move it up, but one below the top (the top
3377                // should always have a real activity).
3378                if (DEBUG_LRU) Slog.d(TAG_LRU,
3379                        "Adding to second-top of LRU activity list: " + app);
3380                mLruProcesses.add(N - 1, app);
3381                // To keep it from spamming the LRU list (by making a bunch of clients),
3382                // we will push down any other entries owned by the app.
3383                final int uid = app.info.uid;
3384                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3385                    ProcessRecord subProc = mLruProcesses.get(i);
3386                    if (subProc.info.uid == uid) {
3387                        // We want to push this one down the list.  If the process after
3388                        // it is for the same uid, however, don't do so, because we don't
3389                        // want them internally to be re-ordered.
3390                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3391                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3392                                    "Pushing uid " + uid + " swapping at " + i + ": "
3393                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3394                            ProcessRecord tmp = mLruProcesses.get(i);
3395                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3396                            mLruProcesses.set(i - 1, tmp);
3397                            i--;
3398                        }
3399                    } else {
3400                        // A gap, we can stop here.
3401                        break;
3402                    }
3403                }
3404            } else {
3405                // Process has activities, put it at the very tipsy-top.
3406                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3407                mLruProcesses.add(app);
3408            }
3409            nextIndex = mLruProcessServiceStart;
3410        } else if (hasService) {
3411            // Process has services, put it at the top of the service list.
3412            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3413            mLruProcesses.add(mLruProcessActivityStart, app);
3414            nextIndex = mLruProcessServiceStart;
3415            mLruProcessActivityStart++;
3416        } else  {
3417            // Process not otherwise of interest, it goes to the top of the non-service area.
3418            int index = mLruProcessServiceStart;
3419            if (client != null) {
3420                // If there is a client, don't allow the process to be moved up higher
3421                // in the list than that client.
3422                int clientIndex = mLruProcesses.lastIndexOf(client);
3423                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3424                        + " when updating " + app);
3425                if (clientIndex <= lrui) {
3426                    // Don't allow the client index restriction to push it down farther in the
3427                    // list than it already is.
3428                    clientIndex = lrui;
3429                }
3430                if (clientIndex >= 0 && index > clientIndex) {
3431                    index = clientIndex;
3432                }
3433            }
3434            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3435            mLruProcesses.add(index, app);
3436            nextIndex = index-1;
3437            mLruProcessActivityStart++;
3438            mLruProcessServiceStart++;
3439        }
3440
3441        // If the app is currently using a content provider or service,
3442        // bump those processes as well.
3443        for (int j=app.connections.size()-1; j>=0; j--) {
3444            ConnectionRecord cr = app.connections.valueAt(j);
3445            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3446                    && cr.binding.service.app != null
3447                    && cr.binding.service.app.lruSeq != mLruSeq
3448                    && !cr.binding.service.app.persistent) {
3449                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3450                        "service connection", cr, app);
3451            }
3452        }
3453        for (int j=app.conProviders.size()-1; j>=0; j--) {
3454            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3455            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3456                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3457                        "provider reference", cpr, app);
3458            }
3459        }
3460    }
3461
3462    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3463        if (uid == Process.SYSTEM_UID) {
3464            // The system gets to run in any process.  If there are multiple
3465            // processes with the same uid, just pick the first (this
3466            // should never happen).
3467            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3468            if (procs == null) return null;
3469            final int procCount = procs.size();
3470            for (int i = 0; i < procCount; i++) {
3471                final int procUid = procs.keyAt(i);
3472                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3473                    // Don't use an app process or different user process for system component.
3474                    continue;
3475                }
3476                return procs.valueAt(i);
3477            }
3478        }
3479        ProcessRecord proc = mProcessNames.get(processName, uid);
3480        if (false && proc != null && !keepIfLarge
3481                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3482                && proc.lastCachedPss >= 4000) {
3483            // Turn this condition on to cause killing to happen regularly, for testing.
3484            if (proc.baseProcessTracker != null) {
3485                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3486            }
3487            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3488        } else if (proc != null && !keepIfLarge
3489                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3490                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3491            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3492            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3493                if (proc.baseProcessTracker != null) {
3494                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3495                }
3496                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3497            }
3498        }
3499        return proc;
3500    }
3501
3502    void notifyPackageUse(String packageName, int reason) {
3503        IPackageManager pm = AppGlobals.getPackageManager();
3504        try {
3505            pm.notifyPackageUse(packageName, reason);
3506        } catch (RemoteException e) {
3507        }
3508    }
3509
3510    boolean isNextTransitionForward() {
3511        int transit = mWindowManager.getPendingAppTransition();
3512        return transit == TRANSIT_ACTIVITY_OPEN
3513                || transit == TRANSIT_TASK_OPEN
3514                || transit == TRANSIT_TASK_TO_FRONT;
3515    }
3516
3517    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3518            String processName, String abiOverride, int uid, Runnable crashHandler) {
3519        synchronized(this) {
3520            ApplicationInfo info = new ApplicationInfo();
3521            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3522            // For isolated processes, the former contains the parent's uid and the latter the
3523            // actual uid of the isolated process.
3524            // In the special case introduced by this method (which is, starting an isolated
3525            // process directly from the SystemServer without an actual parent app process) the
3526            // closest thing to a parent's uid is SYSTEM_UID.
3527            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3528            // the |isolated| logic in the ProcessRecord constructor.
3529            info.uid = Process.SYSTEM_UID;
3530            info.processName = processName;
3531            info.className = entryPoint;
3532            info.packageName = "android";
3533            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3534                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3535                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3536                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3537                    crashHandler);
3538            return proc != null ? proc.pid : 0;
3539        }
3540    }
3541
3542    final ProcessRecord startProcessLocked(String processName,
3543            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3544            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3545            boolean isolated, boolean keepIfLarge) {
3546        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3547                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3548                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3549                null /* crashHandler */);
3550    }
3551
3552    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3553            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3554            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3555            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3556        long startTime = SystemClock.elapsedRealtime();
3557        ProcessRecord app;
3558        if (!isolated) {
3559            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3560            checkTime(startTime, "startProcess: after getProcessRecord");
3561
3562            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3563                // If we are in the background, then check to see if this process
3564                // is bad.  If so, we will just silently fail.
3565                if (mAppErrors.isBadProcessLocked(info)) {
3566                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3567                            + "/" + info.processName);
3568                    return null;
3569                }
3570            } else {
3571                // When the user is explicitly starting a process, then clear its
3572                // crash count so that we won't make it bad until they see at
3573                // least one crash dialog again, and make the process good again
3574                // if it had been bad.
3575                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3576                        + "/" + info.processName);
3577                mAppErrors.resetProcessCrashTimeLocked(info);
3578                if (mAppErrors.isBadProcessLocked(info)) {
3579                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3580                            UserHandle.getUserId(info.uid), info.uid,
3581                            info.processName);
3582                    mAppErrors.clearBadProcessLocked(info);
3583                    if (app != null) {
3584                        app.bad = false;
3585                    }
3586                }
3587            }
3588        } else {
3589            // If this is an isolated process, it can't re-use an existing process.
3590            app = null;
3591        }
3592
3593        // app launch boost for big.little configurations
3594        // use cpusets to migrate freshly launched tasks to big cores
3595        nativeMigrateToBoost();
3596        mIsBoosted = true;
3597        mBoostStartTime = SystemClock.uptimeMillis();
3598        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3599        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3600
3601        // We don't have to do anything more if:
3602        // (1) There is an existing application record; and
3603        // (2) The caller doesn't think it is dead, OR there is no thread
3604        //     object attached to it so we know it couldn't have crashed; and
3605        // (3) There is a pid assigned to it, so it is either starting or
3606        //     already running.
3607        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3608                + " app=" + app + " knownToBeDead=" + knownToBeDead
3609                + " thread=" + (app != null ? app.thread : null)
3610                + " pid=" + (app != null ? app.pid : -1));
3611        if (app != null && app.pid > 0) {
3612            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3613                // We already have the app running, or are waiting for it to
3614                // come up (we have a pid but not yet its thread), so keep it.
3615                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3616                // If this is a new package in the process, add the package to the list
3617                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3618                checkTime(startTime, "startProcess: done, added package to proc");
3619                return app;
3620            }
3621
3622            // An application record is attached to a previous process,
3623            // clean it up now.
3624            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3625            checkTime(startTime, "startProcess: bad proc running, killing");
3626            killProcessGroup(app.uid, app.pid);
3627            handleAppDiedLocked(app, true, true);
3628            checkTime(startTime, "startProcess: done killing old proc");
3629        }
3630
3631        String hostingNameStr = hostingName != null
3632                ? hostingName.flattenToShortString() : null;
3633
3634        if (app == null) {
3635            checkTime(startTime, "startProcess: creating new process record");
3636            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3637            if (app == null) {
3638                Slog.w(TAG, "Failed making new process record for "
3639                        + processName + "/" + info.uid + " isolated=" + isolated);
3640                return null;
3641            }
3642            app.crashHandler = crashHandler;
3643            checkTime(startTime, "startProcess: done creating new process record");
3644        } else {
3645            // If this is a new package in the process, add the package to the list
3646            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3647            checkTime(startTime, "startProcess: added package to existing proc");
3648        }
3649
3650        // If the system is not ready yet, then hold off on starting this
3651        // process until it is.
3652        if (!mProcessesReady
3653                && !isAllowedWhileBooting(info)
3654                && !allowWhileBooting) {
3655            if (!mProcessesOnHold.contains(app)) {
3656                mProcessesOnHold.add(app);
3657            }
3658            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3659                    "System not ready, putting on hold: " + app);
3660            checkTime(startTime, "startProcess: returning with proc on hold");
3661            return app;
3662        }
3663
3664        checkTime(startTime, "startProcess: stepping in to startProcess");
3665        startProcessLocked(
3666                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3667        checkTime(startTime, "startProcess: done starting proc!");
3668        return (app.pid != 0) ? app : null;
3669    }
3670
3671    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3672        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3673    }
3674
3675    private final void startProcessLocked(ProcessRecord app,
3676            String hostingType, String hostingNameStr) {
3677        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3678                null /* entryPoint */, null /* entryPointArgs */);
3679    }
3680
3681    private final void startProcessLocked(ProcessRecord app, String hostingType,
3682            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3683        long startTime = SystemClock.elapsedRealtime();
3684        if (app.pid > 0 && app.pid != MY_PID) {
3685            checkTime(startTime, "startProcess: removing from pids map");
3686            synchronized (mPidsSelfLocked) {
3687                mPidsSelfLocked.remove(app.pid);
3688                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3689            }
3690            checkTime(startTime, "startProcess: done removing from pids map");
3691            app.setPid(0);
3692        }
3693
3694        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3695                "startProcessLocked removing on hold: " + app);
3696        mProcessesOnHold.remove(app);
3697
3698        checkTime(startTime, "startProcess: starting to update cpu stats");
3699        updateCpuStats();
3700        checkTime(startTime, "startProcess: done updating cpu stats");
3701
3702        try {
3703            try {
3704                final int userId = UserHandle.getUserId(app.uid);
3705                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3706            } catch (RemoteException e) {
3707                throw e.rethrowAsRuntimeException();
3708            }
3709
3710            int uid = app.uid;
3711            int[] gids = null;
3712            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3713            if (!app.isolated) {
3714                int[] permGids = null;
3715                try {
3716                    checkTime(startTime, "startProcess: getting gids from package manager");
3717                    final IPackageManager pm = AppGlobals.getPackageManager();
3718                    permGids = pm.getPackageGids(app.info.packageName,
3719                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3720                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3721                            MountServiceInternal.class);
3722                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3723                            app.info.packageName);
3724                } catch (RemoteException e) {
3725                    throw e.rethrowAsRuntimeException();
3726                }
3727
3728                /*
3729                 * Add shared application and profile GIDs so applications can share some
3730                 * resources like shared libraries and access user-wide resources
3731                 */
3732                if (ArrayUtils.isEmpty(permGids)) {
3733                    gids = new int[3];
3734                } else {
3735                    gids = new int[permGids.length + 3];
3736                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3737                }
3738                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3739                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3740                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3741            }
3742            checkTime(startTime, "startProcess: building args");
3743            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3744                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3745                        && mTopComponent != null
3746                        && app.processName.equals(mTopComponent.getPackageName())) {
3747                    uid = 0;
3748                }
3749                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3750                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3751                    uid = 0;
3752                }
3753            }
3754            int debugFlags = 0;
3755            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3756                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3757                // Also turn on CheckJNI for debuggable apps. It's quite
3758                // awkward to turn on otherwise.
3759                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3760            }
3761            // Run the app in safe mode if its manifest requests so or the
3762            // system is booted in safe mode.
3763            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3764                mSafeMode == true) {
3765                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3766            }
3767            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3768                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3769            }
3770            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3771            if ("true".equals(genDebugInfoProperty)) {
3772                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3773            }
3774            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3775                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3776            }
3777            if ("1".equals(SystemProperties.get("debug.assert"))) {
3778                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3779            }
3780            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3781                // Enable all debug flags required by the native debugger.
3782                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3783                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3784                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3785                mNativeDebuggingApp = null;
3786            }
3787
3788            String invokeWith = null;
3789            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3790                // Debuggable apps may include a wrapper script with their library directory.
3791                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3792                if (new File(wrapperFileName).exists()) {
3793                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3794                }
3795            }
3796
3797            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3798            if (requiredAbi == null) {
3799                requiredAbi = Build.SUPPORTED_ABIS[0];
3800            }
3801
3802            String instructionSet = null;
3803            if (app.info.primaryCpuAbi != null) {
3804                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3805            }
3806
3807            app.gids = gids;
3808            app.requiredAbi = requiredAbi;
3809            app.instructionSet = instructionSet;
3810
3811            // Start the process.  It will either succeed and return a result containing
3812            // the PID of the new process, or else throw a RuntimeException.
3813            boolean isActivityProcess = (entryPoint == null);
3814            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3815            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3816                    app.processName);
3817            checkTime(startTime, "startProcess: asking zygote to start proc");
3818            Process.ProcessStartResult startResult;
3819            if (hostingType.equals("webview_service")) {
3820                startResult = Process.startWebView(entryPoint,
3821                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3822                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3823                        app.info.dataDir, null, entryPointArgs);
3824            } else {
3825                startResult = Process.start(entryPoint,
3826                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3827                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3828                        app.info.dataDir, invokeWith, entryPointArgs);
3829            }
3830            checkTime(startTime, "startProcess: returned from zygote!");
3831            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3832
3833            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3834            checkTime(startTime, "startProcess: done updating battery stats");
3835
3836            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3837                    UserHandle.getUserId(uid), startResult.pid, uid,
3838                    app.processName, hostingType,
3839                    hostingNameStr != null ? hostingNameStr : "");
3840
3841            try {
3842                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3843                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3844            } catch (RemoteException ex) {
3845                // Ignore
3846            }
3847
3848            if (app.persistent) {
3849                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3850            }
3851
3852            checkTime(startTime, "startProcess: building log message");
3853            StringBuilder buf = mStringBuilder;
3854            buf.setLength(0);
3855            buf.append("Start proc ");
3856            buf.append(startResult.pid);
3857            buf.append(':');
3858            buf.append(app.processName);
3859            buf.append('/');
3860            UserHandle.formatUid(buf, uid);
3861            if (!isActivityProcess) {
3862                buf.append(" [");
3863                buf.append(entryPoint);
3864                buf.append("]");
3865            }
3866            buf.append(" for ");
3867            buf.append(hostingType);
3868            if (hostingNameStr != null) {
3869                buf.append(" ");
3870                buf.append(hostingNameStr);
3871            }
3872            Slog.i(TAG, buf.toString());
3873            app.setPid(startResult.pid);
3874            app.usingWrapper = startResult.usingWrapper;
3875            app.removed = false;
3876            app.killed = false;
3877            app.killedByAm = false;
3878            checkTime(startTime, "startProcess: starting to update pids map");
3879            ProcessRecord oldApp;
3880            synchronized (mPidsSelfLocked) {
3881                oldApp = mPidsSelfLocked.get(startResult.pid);
3882            }
3883            // If there is already an app occupying that pid that hasn't been cleaned up
3884            if (oldApp != null && !app.isolated) {
3885                // Clean up anything relating to this pid first
3886                Slog.w(TAG, "Reusing pid " + startResult.pid
3887                        + " while app is still mapped to it");
3888                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3889                        true /*replacingPid*/);
3890            }
3891            synchronized (mPidsSelfLocked) {
3892                this.mPidsSelfLocked.put(startResult.pid, app);
3893                if (isActivityProcess) {
3894                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3895                    msg.obj = app;
3896                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3897                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3898                }
3899            }
3900            checkTime(startTime, "startProcess: done updating pids map");
3901        } catch (RuntimeException e) {
3902            Slog.e(TAG, "Failure starting process " + app.processName, e);
3903
3904            // Something went very wrong while trying to start this process; one
3905            // common case is when the package is frozen due to an active
3906            // upgrade. To recover, clean up any active bookkeeping related to
3907            // starting this process. (We already invoked this method once when
3908            // the package was initially frozen through KILL_APPLICATION_MSG, so
3909            // it doesn't hurt to use it again.)
3910            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3911                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3912        }
3913    }
3914
3915    void updateUsageStats(ActivityRecord component, boolean resumed) {
3916        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3917                "updateUsageStats: comp=" + component + "res=" + resumed);
3918        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3919        if (resumed) {
3920            if (mUsageStatsService != null) {
3921                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3922                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3923            }
3924            synchronized (stats) {
3925                stats.noteActivityResumedLocked(component.app.uid);
3926            }
3927        } else {
3928            if (mUsageStatsService != null) {
3929                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3930                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3931            }
3932            synchronized (stats) {
3933                stats.noteActivityPausedLocked(component.app.uid);
3934            }
3935        }
3936    }
3937
3938    Intent getHomeIntent() {
3939        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3940        intent.setComponent(mTopComponent);
3941        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3942        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3943            intent.addCategory(Intent.CATEGORY_HOME);
3944        }
3945        return intent;
3946    }
3947
3948    boolean startHomeActivityLocked(int userId, String reason) {
3949        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3950                && mTopAction == null) {
3951            // We are running in factory test mode, but unable to find
3952            // the factory test app, so just sit around displaying the
3953            // error message and don't try to start anything.
3954            return false;
3955        }
3956        Intent intent = getHomeIntent();
3957        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3958        if (aInfo != null) {
3959            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3960            // Don't do this if the home app is currently being
3961            // instrumented.
3962            aInfo = new ActivityInfo(aInfo);
3963            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3964            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3965                    aInfo.applicationInfo.uid, true);
3966            if (app == null || app.instrumentationClass == null) {
3967                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3968                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3969            }
3970        } else {
3971            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3972        }
3973
3974        return true;
3975    }
3976
3977    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3978        ActivityInfo ai = null;
3979        ComponentName comp = intent.getComponent();
3980        try {
3981            if (comp != null) {
3982                // Factory test.
3983                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3984            } else {
3985                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3986                        intent,
3987                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3988                        flags, userId);
3989
3990                if (info != null) {
3991                    ai = info.activityInfo;
3992                }
3993            }
3994        } catch (RemoteException e) {
3995            // ignore
3996        }
3997
3998        return ai;
3999    }
4000
4001    /**
4002     * Starts the "new version setup screen" if appropriate.
4003     */
4004    void startSetupActivityLocked() {
4005        // Only do this once per boot.
4006        if (mCheckedForSetup) {
4007            return;
4008        }
4009
4010        // We will show this screen if the current one is a different
4011        // version than the last one shown, and we are not running in
4012        // low-level factory test mode.
4013        final ContentResolver resolver = mContext.getContentResolver();
4014        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4015                Settings.Global.getInt(resolver,
4016                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4017            mCheckedForSetup = true;
4018
4019            // See if we should be showing the platform update setup UI.
4020            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4021            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4022                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4023            if (!ris.isEmpty()) {
4024                final ResolveInfo ri = ris.get(0);
4025                String vers = ri.activityInfo.metaData != null
4026                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4027                        : null;
4028                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4029                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4030                            Intent.METADATA_SETUP_VERSION);
4031                }
4032                String lastVers = Settings.Secure.getString(
4033                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4034                if (vers != null && !vers.equals(lastVers)) {
4035                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4036                    intent.setComponent(new ComponentName(
4037                            ri.activityInfo.packageName, ri.activityInfo.name));
4038                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4039                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4040                            null, 0, 0, 0, null, false, false, null, null, null);
4041                }
4042            }
4043        }
4044    }
4045
4046    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4047        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4048    }
4049
4050    void enforceNotIsolatedCaller(String caller) {
4051        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4052            throw new SecurityException("Isolated process not allowed to call " + caller);
4053        }
4054    }
4055
4056    void enforceShellRestriction(String restriction, int userHandle) {
4057        if (Binder.getCallingUid() == Process.SHELL_UID) {
4058            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4059                throw new SecurityException("Shell does not have permission to access user "
4060                        + userHandle);
4061            }
4062        }
4063    }
4064
4065    @Override
4066    public int getFrontActivityScreenCompatMode() {
4067        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4068        synchronized (this) {
4069            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4070        }
4071    }
4072
4073    @Override
4074    public void setFrontActivityScreenCompatMode(int mode) {
4075        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4076                "setFrontActivityScreenCompatMode");
4077        synchronized (this) {
4078            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4079        }
4080    }
4081
4082    @Override
4083    public int getPackageScreenCompatMode(String packageName) {
4084        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4085        synchronized (this) {
4086            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4087        }
4088    }
4089
4090    @Override
4091    public void setPackageScreenCompatMode(String packageName, int mode) {
4092        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4093                "setPackageScreenCompatMode");
4094        synchronized (this) {
4095            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4096        }
4097    }
4098
4099    @Override
4100    public boolean getPackageAskScreenCompat(String packageName) {
4101        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4102        synchronized (this) {
4103            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4104        }
4105    }
4106
4107    @Override
4108    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4109        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4110                "setPackageAskScreenCompat");
4111        synchronized (this) {
4112            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4113        }
4114    }
4115
4116    private boolean hasUsageStatsPermission(String callingPackage) {
4117        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4118                Binder.getCallingUid(), callingPackage);
4119        if (mode == AppOpsManager.MODE_DEFAULT) {
4120            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4121                    == PackageManager.PERMISSION_GRANTED;
4122        }
4123        return mode == AppOpsManager.MODE_ALLOWED;
4124    }
4125
4126    @Override
4127    public int getPackageProcessState(String packageName, String callingPackage) {
4128        if (!hasUsageStatsPermission(callingPackage)) {
4129            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4130                    "getPackageProcessState");
4131        }
4132
4133        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4134        synchronized (this) {
4135            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4136                final ProcessRecord proc = mLruProcesses.get(i);
4137                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4138                        || procState > proc.setProcState) {
4139                    boolean found = false;
4140                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4141                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4142                            procState = proc.setProcState;
4143                            found = true;
4144                        }
4145                    }
4146                    if (proc.pkgDeps != null && !found) {
4147                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4148                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4149                                procState = proc.setProcState;
4150                                break;
4151                            }
4152                        }
4153                    }
4154                }
4155            }
4156        }
4157        return procState;
4158    }
4159
4160    @Override
4161    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4162        synchronized (this) {
4163            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4164            if (app == null) {
4165                return false;
4166            }
4167            if (app.trimMemoryLevel < level && app.thread != null &&
4168                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4169                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4170                try {
4171                    app.thread.scheduleTrimMemory(level);
4172                    app.trimMemoryLevel = level;
4173                    return true;
4174                } catch (RemoteException e) {
4175                    // Fallthrough to failure case.
4176                }
4177            }
4178        }
4179        return false;
4180    }
4181
4182    private void dispatchProcessesChanged() {
4183        int N;
4184        synchronized (this) {
4185            N = mPendingProcessChanges.size();
4186            if (mActiveProcessChanges.length < N) {
4187                mActiveProcessChanges = new ProcessChangeItem[N];
4188            }
4189            mPendingProcessChanges.toArray(mActiveProcessChanges);
4190            mPendingProcessChanges.clear();
4191            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                    "*** Delivering " + N + " process changes");
4193        }
4194
4195        int i = mProcessObservers.beginBroadcast();
4196        while (i > 0) {
4197            i--;
4198            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4199            if (observer != null) {
4200                try {
4201                    for (int j=0; j<N; j++) {
4202                        ProcessChangeItem item = mActiveProcessChanges[j];
4203                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4204                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4205                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4206                                    + item.uid + ": " + item.foregroundActivities);
4207                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4208                                    item.foregroundActivities);
4209                        }
4210                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4211                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4212                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4213                                    + ": " + item.processState);
4214                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4215                        }
4216                    }
4217                } catch (RemoteException e) {
4218                }
4219            }
4220        }
4221        mProcessObservers.finishBroadcast();
4222
4223        synchronized (this) {
4224            for (int j=0; j<N; j++) {
4225                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4226            }
4227        }
4228    }
4229
4230    private void dispatchProcessDied(int pid, int uid) {
4231        int i = mProcessObservers.beginBroadcast();
4232        while (i > 0) {
4233            i--;
4234            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4235            if (observer != null) {
4236                try {
4237                    observer.onProcessDied(pid, uid);
4238                } catch (RemoteException e) {
4239                }
4240            }
4241        }
4242        mProcessObservers.finishBroadcast();
4243    }
4244
4245    private void dispatchUidsChanged() {
4246        int N;
4247        synchronized (this) {
4248            N = mPendingUidChanges.size();
4249            if (mActiveUidChanges.length < N) {
4250                mActiveUidChanges = new UidRecord.ChangeItem[N];
4251            }
4252            for (int i=0; i<N; i++) {
4253                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4254                mActiveUidChanges[i] = change;
4255                if (change.uidRecord != null) {
4256                    change.uidRecord.pendingChange = null;
4257                    change.uidRecord = null;
4258                }
4259            }
4260            mPendingUidChanges.clear();
4261            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4262                    "*** Delivering " + N + " uid changes");
4263        }
4264
4265        if (mLocalPowerManager != null) {
4266            for (int j=0; j<N; j++) {
4267                UidRecord.ChangeItem item = mActiveUidChanges[j];
4268                if (item.change == UidRecord.CHANGE_GONE
4269                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4270                    mLocalPowerManager.uidGone(item.uid);
4271                } else {
4272                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4273                }
4274            }
4275        }
4276
4277        int i = mUidObservers.beginBroadcast();
4278        while (i > 0) {
4279            i--;
4280            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4281            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4282            if (observer != null) {
4283                try {
4284                    for (int j=0; j<N; j++) {
4285                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4286                        final int change = item.change;
4287                        UidRecord validateUid = null;
4288                        if (VALIDATE_UID_STATES && i == 0) {
4289                            validateUid = mValidateUids.get(item.uid);
4290                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4291                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4292                                validateUid = new UidRecord(item.uid);
4293                                mValidateUids.put(item.uid, validateUid);
4294                            }
4295                        }
4296                        if (change == UidRecord.CHANGE_IDLE
4297                                || change == UidRecord.CHANGE_GONE_IDLE) {
4298                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4299                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4300                                        "UID idle uid=" + item.uid);
4301                                observer.onUidIdle(item.uid);
4302                            }
4303                            if (VALIDATE_UID_STATES && i == 0) {
4304                                if (validateUid != null) {
4305                                    validateUid.idle = true;
4306                                }
4307                            }
4308                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4309                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4310                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4311                                        "UID active uid=" + item.uid);
4312                                observer.onUidActive(item.uid);
4313                            }
4314                            if (VALIDATE_UID_STATES && i == 0) {
4315                                validateUid.idle = false;
4316                            }
4317                        }
4318                        if (change == UidRecord.CHANGE_GONE
4319                                || change == UidRecord.CHANGE_GONE_IDLE) {
4320                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4321                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4322                                        "UID gone uid=" + item.uid);
4323                                observer.onUidGone(item.uid);
4324                            }
4325                            if (VALIDATE_UID_STATES && i == 0) {
4326                                if (validateUid != null) {
4327                                    mValidateUids.remove(item.uid);
4328                                }
4329                            }
4330                        } else {
4331                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4332                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4333                                        "UID CHANGED uid=" + item.uid
4334                                                + ": " + item.processState);
4335                                observer.onUidStateChanged(item.uid, item.processState);
4336                            }
4337                            if (VALIDATE_UID_STATES && i == 0) {
4338                                validateUid.curProcState = validateUid.setProcState
4339                                        = item.processState;
4340                            }
4341                        }
4342                    }
4343                } catch (RemoteException e) {
4344                }
4345            }
4346        }
4347        mUidObservers.finishBroadcast();
4348
4349        synchronized (this) {
4350            for (int j=0; j<N; j++) {
4351                mAvailUidChanges.add(mActiveUidChanges[j]);
4352            }
4353        }
4354    }
4355
4356    @Override
4357    public final int startActivity(IApplicationThread caller, String callingPackage,
4358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4360        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4361                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4362                UserHandle.getCallingUserId());
4363    }
4364
4365    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4366        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4367        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4368                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4369                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4370
4371        // TODO: Switch to user app stacks here.
4372        String mimeType = intent.getType();
4373        final Uri data = intent.getData();
4374        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4375            mimeType = getProviderMimeType(data, userId);
4376        }
4377        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4378
4379        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4380        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4381                null, 0, 0, null, null, null, null, false, userId, container, null);
4382    }
4383
4384    @Override
4385    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4386            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4387            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4388        enforceNotIsolatedCaller("startActivity");
4389        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4390                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4393                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4394                profilerInfo, null, null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4399            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4400            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4401            int userId) {
4402
4403        // This is very dangerous -- it allows you to perform a start activity (including
4404        // permission grants) as any app that may launch one of your own activities.  So
4405        // we will only allow this to be done from activities that are part of the core framework,
4406        // and then only when they are running as the system.
4407        final ActivityRecord sourceRecord;
4408        final int targetUid;
4409        final String targetPackage;
4410        synchronized (this) {
4411            if (resultTo == null) {
4412                throw new SecurityException("Must be called from an activity");
4413            }
4414            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4415            if (sourceRecord == null) {
4416                throw new SecurityException("Called with bad activity token: " + resultTo);
4417            }
4418            if (!sourceRecord.info.packageName.equals("android")) {
4419                throw new SecurityException(
4420                        "Must be called from an activity that is declared in the android package");
4421            }
4422            if (sourceRecord.app == null) {
4423                throw new SecurityException("Called without a process attached to activity");
4424            }
4425            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4426                // This is still okay, as long as this activity is running under the
4427                // uid of the original calling activity.
4428                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4429                    throw new SecurityException(
4430                            "Calling activity in uid " + sourceRecord.app.uid
4431                                    + " must be system uid or original calling uid "
4432                                    + sourceRecord.launchedFromUid);
4433                }
4434            }
4435            if (ignoreTargetSecurity) {
4436                if (intent.getComponent() == null) {
4437                    throw new SecurityException(
4438                            "Component must be specified with ignoreTargetSecurity");
4439                }
4440                if (intent.getSelector() != null) {
4441                    throw new SecurityException(
4442                            "Selector not allowed with ignoreTargetSecurity");
4443                }
4444            }
4445            targetUid = sourceRecord.launchedFromUid;
4446            targetPackage = sourceRecord.launchedFromPackage;
4447        }
4448
4449        if (userId == UserHandle.USER_NULL) {
4450            userId = UserHandle.getUserId(sourceRecord.app.uid);
4451        }
4452
4453        // TODO: Switch to user app stacks here.
4454        try {
4455            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4456                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4457                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4458            return ret;
4459        } catch (SecurityException e) {
4460            // XXX need to figure out how to propagate to original app.
4461            // A SecurityException here is generally actually a fault of the original
4462            // calling activity (such as a fairly granting permissions), so propagate it
4463            // back to them.
4464            /*
4465            StringBuilder msg = new StringBuilder();
4466            msg.append("While launching");
4467            msg.append(intent.toString());
4468            msg.append(": ");
4469            msg.append(e.getMessage());
4470            */
4471            throw e;
4472        }
4473    }
4474
4475    @Override
4476    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4477            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4478            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4479        enforceNotIsolatedCaller("startActivityAndWait");
4480        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4481                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4482        WaitResult res = new WaitResult();
4483        // TODO: Switch to user app stacks here.
4484        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4485                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4486                bOptions, false, userId, null, null);
4487        return res;
4488    }
4489
4490    @Override
4491    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4492            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4493            int startFlags, Configuration config, Bundle bOptions, int userId) {
4494        enforceNotIsolatedCaller("startActivityWithConfig");
4495        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4496                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4497        // TODO: Switch to user app stacks here.
4498        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4499                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4500                null, null, config, bOptions, false, userId, null, null);
4501        return ret;
4502    }
4503
4504    @Override
4505    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4506            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4507            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4508            throws TransactionTooLargeException {
4509        enforceNotIsolatedCaller("startActivityIntentSender");
4510        // Refuse possible leaked file descriptors
4511        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4512            throw new IllegalArgumentException("File descriptors passed in Intent");
4513        }
4514
4515        IIntentSender sender = intent.getTarget();
4516        if (!(sender instanceof PendingIntentRecord)) {
4517            throw new IllegalArgumentException("Bad PendingIntent object");
4518        }
4519
4520        PendingIntentRecord pir = (PendingIntentRecord)sender;
4521
4522        synchronized (this) {
4523            // If this is coming from the currently resumed activity, it is
4524            // effectively saying that app switches are allowed at this point.
4525            final ActivityStack stack = getFocusedStack();
4526            if (stack.mResumedActivity != null &&
4527                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4528                mAppSwitchesAllowedTime = 0;
4529            }
4530        }
4531        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4532                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4533        return ret;
4534    }
4535
4536    @Override
4537    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4538            Intent intent, String resolvedType, IVoiceInteractionSession session,
4539            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4540            Bundle bOptions, int userId) {
4541        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4542                != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: startVoiceActivity() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550        if (session == null || interactor == null) {
4551            throw new NullPointerException("null session or interactor");
4552        }
4553        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4554                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4555        // TODO: Switch to user app stacks here.
4556        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4557                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4558                null, bOptions, false, userId, null, null);
4559    }
4560
4561    @Override
4562    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4563            throws RemoteException {
4564        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4565        synchronized (this) {
4566            ActivityRecord activity = getFocusedStack().topActivity();
4567            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4568                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4569            }
4570            if (mRunningVoice != null || activity.task.voiceSession != null
4571                    || activity.voiceSession != null) {
4572                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4573                return;
4574            }
4575            if (activity.pendingVoiceInteractionStart) {
4576                Slog.w(TAG, "Pending start of voice interaction already.");
4577                return;
4578            }
4579            activity.pendingVoiceInteractionStart = true;
4580        }
4581        LocalServices.getService(VoiceInteractionManagerInternal.class)
4582                .startLocalVoiceInteraction(callingActivity, options);
4583    }
4584
4585    @Override
4586    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4587        LocalServices.getService(VoiceInteractionManagerInternal.class)
4588                .stopLocalVoiceInteraction(callingActivity);
4589    }
4590
4591    @Override
4592    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4593        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4594                .supportsLocalVoiceInteraction();
4595    }
4596
4597    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4598            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4599        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4600        if (activityToCallback == null) return;
4601        activityToCallback.setVoiceSessionLocked(voiceSession);
4602
4603        // Inform the activity
4604        try {
4605            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4606                    voiceInteractor);
4607            long token = Binder.clearCallingIdentity();
4608            try {
4609                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4610            } finally {
4611                Binder.restoreCallingIdentity(token);
4612            }
4613            // TODO: VI Should we cache the activity so that it's easier to find later
4614            // rather than scan through all the stacks and activities?
4615        } catch (RemoteException re) {
4616            activityToCallback.clearVoiceSessionLocked();
4617            // TODO: VI Should this terminate the voice session?
4618        }
4619    }
4620
4621    @Override
4622    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4623        synchronized (this) {
4624            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4625                if (keepAwake) {
4626                    mVoiceWakeLock.acquire();
4627                } else {
4628                    mVoiceWakeLock.release();
4629                }
4630            }
4631        }
4632    }
4633
4634    @Override
4635    public boolean startNextMatchingActivity(IBinder callingActivity,
4636            Intent intent, Bundle bOptions) {
4637        // Refuse possible leaked file descriptors
4638        if (intent != null && intent.hasFileDescriptors() == true) {
4639            throw new IllegalArgumentException("File descriptors passed in Intent");
4640        }
4641        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4642
4643        synchronized (this) {
4644            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4645            if (r == null) {
4646                ActivityOptions.abort(options);
4647                return false;
4648            }
4649            if (r.app == null || r.app.thread == null) {
4650                // The caller is not running...  d'oh!
4651                ActivityOptions.abort(options);
4652                return false;
4653            }
4654            intent = new Intent(intent);
4655            // The caller is not allowed to change the data.
4656            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4657            // And we are resetting to find the next component...
4658            intent.setComponent(null);
4659
4660            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4661
4662            ActivityInfo aInfo = null;
4663            try {
4664                List<ResolveInfo> resolves =
4665                    AppGlobals.getPackageManager().queryIntentActivities(
4666                            intent, r.resolvedType,
4667                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4668                            UserHandle.getCallingUserId()).getList();
4669
4670                // Look for the original activity in the list...
4671                final int N = resolves != null ? resolves.size() : 0;
4672                for (int i=0; i<N; i++) {
4673                    ResolveInfo rInfo = resolves.get(i);
4674                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4675                            && rInfo.activityInfo.name.equals(r.info.name)) {
4676                        // We found the current one...  the next matching is
4677                        // after it.
4678                        i++;
4679                        if (i<N) {
4680                            aInfo = resolves.get(i).activityInfo;
4681                        }
4682                        if (debug) {
4683                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4684                                    + "/" + r.info.name);
4685                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4686                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4687                        }
4688                        break;
4689                    }
4690                }
4691            } catch (RemoteException e) {
4692            }
4693
4694            if (aInfo == null) {
4695                // Nobody who is next!
4696                ActivityOptions.abort(options);
4697                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4698                return false;
4699            }
4700
4701            intent.setComponent(new ComponentName(
4702                    aInfo.applicationInfo.packageName, aInfo.name));
4703            intent.setFlags(intent.getFlags()&~(
4704                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4705                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4706                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4707                    Intent.FLAG_ACTIVITY_NEW_TASK));
4708
4709            // Okay now we need to start the new activity, replacing the
4710            // currently running activity.  This is a little tricky because
4711            // we want to start the new one as if the current one is finished,
4712            // but not finish the current one first so that there is no flicker.
4713            // And thus...
4714            final boolean wasFinishing = r.finishing;
4715            r.finishing = true;
4716
4717            // Propagate reply information over to the new activity.
4718            final ActivityRecord resultTo = r.resultTo;
4719            final String resultWho = r.resultWho;
4720            final int requestCode = r.requestCode;
4721            r.resultTo = null;
4722            if (resultTo != null) {
4723                resultTo.removeResultsLocked(r, resultWho, requestCode);
4724            }
4725
4726            final long origId = Binder.clearCallingIdentity();
4727            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4728                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4729                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4730                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4731                    false, false, null, null, null);
4732            Binder.restoreCallingIdentity(origId);
4733
4734            r.finishing = wasFinishing;
4735            if (res != ActivityManager.START_SUCCESS) {
4736                return false;
4737            }
4738            return true;
4739        }
4740    }
4741
4742    @Override
4743    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4744        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4745            String msg = "Permission Denial: startActivityFromRecents called without " +
4746                    START_TASKS_FROM_RECENTS;
4747            Slog.w(TAG, msg);
4748            throw new SecurityException(msg);
4749        }
4750        final long origId = Binder.clearCallingIdentity();
4751        try {
4752            synchronized (this) {
4753                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4754            }
4755        } finally {
4756            Binder.restoreCallingIdentity(origId);
4757        }
4758    }
4759
4760    final int startActivityInPackage(int uid, String callingPackage,
4761            Intent intent, String resolvedType, IBinder resultTo,
4762            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4763            IActivityContainer container, TaskRecord inTask) {
4764
4765        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4766                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4767
4768        // TODO: Switch to user app stacks here.
4769        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4770                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4771                null, null, null, bOptions, false, userId, container, inTask);
4772        return ret;
4773    }
4774
4775    @Override
4776    public final int startActivities(IApplicationThread caller, String callingPackage,
4777            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4778            int userId) {
4779        enforceNotIsolatedCaller("startActivities");
4780        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4781                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4782        // TODO: Switch to user app stacks here.
4783        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4784                resolvedTypes, resultTo, bOptions, userId);
4785        return ret;
4786    }
4787
4788    final int startActivitiesInPackage(int uid, String callingPackage,
4789            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4790            Bundle bOptions, int userId) {
4791
4792        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4793                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4794        // TODO: Switch to user app stacks here.
4795        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4796                resultTo, bOptions, userId);
4797        return ret;
4798    }
4799
4800    @Override
4801    public void reportActivityFullyDrawn(IBinder token) {
4802        synchronized (this) {
4803            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4804            if (r == null) {
4805                return;
4806            }
4807            r.reportFullyDrawnLocked();
4808        }
4809    }
4810
4811    @Override
4812    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4813        synchronized (this) {
4814            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4815            if (r == null) {
4816                return;
4817            }
4818            TaskRecord task = r.task;
4819            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4820                // Fixed screen orientation isn't supported when activities aren't in full screen
4821                // mode.
4822                return;
4823            }
4824            final long origId = Binder.clearCallingIdentity();
4825            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4826            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4827                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4828            if (config != null) {
4829                r.frozenBeforeDestroy = true;
4830                if (!updateConfigurationLocked(config, r, false)) {
4831                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4832                }
4833            }
4834            Binder.restoreCallingIdentity(origId);
4835        }
4836    }
4837
4838    @Override
4839    public int getRequestedOrientation(IBinder token) {
4840        synchronized (this) {
4841            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4842            if (r == null) {
4843                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4844            }
4845            return mWindowManager.getAppOrientation(r.appToken);
4846        }
4847    }
4848
4849    /**
4850     * This is the internal entry point for handling Activity.finish().
4851     *
4852     * @param token The Binder token referencing the Activity we want to finish.
4853     * @param resultCode Result code, if any, from this Activity.
4854     * @param resultData Result data (Intent), if any, from this Activity.
4855     * @param finishTask Whether to finish the task associated with this Activity.
4856     *
4857     * @return Returns true if the activity successfully finished, or false if it is still running.
4858     */
4859    @Override
4860    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4861            int finishTask) {
4862        // Refuse possible leaked file descriptors
4863        if (resultData != null && resultData.hasFileDescriptors() == true) {
4864            throw new IllegalArgumentException("File descriptors passed in Intent");
4865        }
4866
4867        synchronized(this) {
4868            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4869            if (r == null) {
4870                return true;
4871            }
4872            // Keep track of the root activity of the task before we finish it
4873            TaskRecord tr = r.task;
4874            ActivityRecord rootR = tr.getRootActivity();
4875            if (rootR == null) {
4876                Slog.w(TAG, "Finishing task with all activities already finished");
4877            }
4878            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4879            // finish.
4880            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4881                    mStackSupervisor.isLastLockedTask(tr)) {
4882                Slog.i(TAG, "Not finishing task in lock task mode");
4883                mStackSupervisor.showLockTaskToast();
4884                return false;
4885            }
4886            if (mController != null) {
4887                // Find the first activity that is not finishing.
4888                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4889                if (next != null) {
4890                    // ask watcher if this is allowed
4891                    boolean resumeOK = true;
4892                    try {
4893                        resumeOK = mController.activityResuming(next.packageName);
4894                    } catch (RemoteException e) {
4895                        mController = null;
4896                        Watchdog.getInstance().setActivityController(null);
4897                    }
4898
4899                    if (!resumeOK) {
4900                        Slog.i(TAG, "Not finishing activity because controller resumed");
4901                        return false;
4902                    }
4903                }
4904            }
4905            final long origId = Binder.clearCallingIdentity();
4906            try {
4907                boolean res;
4908                final boolean finishWithRootActivity =
4909                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4910                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4911                        || (finishWithRootActivity && r == rootR)) {
4912                    // If requested, remove the task that is associated to this activity only if it
4913                    // was the root activity in the task. The result code and data is ignored
4914                    // because we don't support returning them across task boundaries. Also, to
4915                    // keep backwards compatibility we remove the task from recents when finishing
4916                    // task with root activity.
4917                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4918                    if (!res) {
4919                        Slog.i(TAG, "Removing task failed to finish activity");
4920                    }
4921                } else {
4922                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4923                            resultData, "app-request", true);
4924                    if (!res) {
4925                        Slog.i(TAG, "Failed to finish by app-request");
4926                    }
4927                }
4928                return res;
4929            } finally {
4930                Binder.restoreCallingIdentity(origId);
4931            }
4932        }
4933    }
4934
4935    @Override
4936    public final void finishHeavyWeightApp() {
4937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4938                != PackageManager.PERMISSION_GRANTED) {
4939            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4940                    + Binder.getCallingPid()
4941                    + ", uid=" + Binder.getCallingUid()
4942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4943            Slog.w(TAG, msg);
4944            throw new SecurityException(msg);
4945        }
4946
4947        synchronized(this) {
4948            if (mHeavyWeightProcess == null) {
4949                return;
4950            }
4951
4952            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4953            for (int i = 0; i < activities.size(); i++) {
4954                ActivityRecord r = activities.get(i);
4955                if (!r.finishing && r.isInStackLocked()) {
4956                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4957                            null, "finish-heavy", true);
4958                }
4959            }
4960
4961            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4962                    mHeavyWeightProcess.userId, 0));
4963            mHeavyWeightProcess = null;
4964        }
4965    }
4966
4967    @Override
4968    public void crashApplication(int uid, int initialPid, String packageName,
4969            String message) {
4970        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4971                != PackageManager.PERMISSION_GRANTED) {
4972            String msg = "Permission Denial: crashApplication() from pid="
4973                    + Binder.getCallingPid()
4974                    + ", uid=" + Binder.getCallingUid()
4975                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4976            Slog.w(TAG, msg);
4977            throw new SecurityException(msg);
4978        }
4979
4980        synchronized(this) {
4981            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4982        }
4983    }
4984
4985    @Override
4986    public final void finishSubActivity(IBinder token, String resultWho,
4987            int requestCode) {
4988        synchronized(this) {
4989            final long origId = Binder.clearCallingIdentity();
4990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991            if (r != null) {
4992                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4993            }
4994            Binder.restoreCallingIdentity(origId);
4995        }
4996    }
4997
4998    @Override
4999    public boolean finishActivityAffinity(IBinder token) {
5000        synchronized(this) {
5001            final long origId = Binder.clearCallingIdentity();
5002            try {
5003                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5004                if (r == null) {
5005                    return false;
5006                }
5007
5008                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5009                // can finish.
5010                final TaskRecord task = r.task;
5011                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5012                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5013                    mStackSupervisor.showLockTaskToast();
5014                    return false;
5015                }
5016                return task.stack.finishActivityAffinityLocked(r);
5017            } finally {
5018                Binder.restoreCallingIdentity(origId);
5019            }
5020        }
5021    }
5022
5023    @Override
5024    public void finishVoiceTask(IVoiceInteractionSession session) {
5025        synchronized (this) {
5026            final long origId = Binder.clearCallingIdentity();
5027            try {
5028                // TODO: VI Consider treating local voice interactions and voice tasks
5029                // differently here
5030                mStackSupervisor.finishVoiceTask(session);
5031            } finally {
5032                Binder.restoreCallingIdentity(origId);
5033            }
5034        }
5035
5036    }
5037
5038    @Override
5039    public boolean releaseActivityInstance(IBinder token) {
5040        synchronized(this) {
5041            final long origId = Binder.clearCallingIdentity();
5042            try {
5043                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5044                if (r == null) {
5045                    return false;
5046                }
5047                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5048            } finally {
5049                Binder.restoreCallingIdentity(origId);
5050            }
5051        }
5052    }
5053
5054    @Override
5055    public void releaseSomeActivities(IApplicationThread appInt) {
5056        synchronized(this) {
5057            final long origId = Binder.clearCallingIdentity();
5058            try {
5059                ProcessRecord app = getRecordForAppLocked(appInt);
5060                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5061            } finally {
5062                Binder.restoreCallingIdentity(origId);
5063            }
5064        }
5065    }
5066
5067    @Override
5068    public boolean willActivityBeVisible(IBinder token) {
5069        synchronized(this) {
5070            ActivityStack stack = ActivityRecord.getStackLocked(token);
5071            if (stack != null) {
5072                return stack.willActivityBeVisibleLocked(token);
5073            }
5074            return false;
5075        }
5076    }
5077
5078    @Override
5079    public void overridePendingTransition(IBinder token, String packageName,
5080            int enterAnim, int exitAnim) {
5081        synchronized(this) {
5082            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5083            if (self == null) {
5084                return;
5085            }
5086
5087            final long origId = Binder.clearCallingIdentity();
5088
5089            if (self.state == ActivityState.RESUMED
5090                    || self.state == ActivityState.PAUSING) {
5091                mWindowManager.overridePendingAppTransition(packageName,
5092                        enterAnim, exitAnim, null);
5093            }
5094
5095            Binder.restoreCallingIdentity(origId);
5096        }
5097    }
5098
5099    /**
5100     * Main function for removing an existing process from the activity manager
5101     * as a result of that process going away.  Clears out all connections
5102     * to the process.
5103     */
5104    private final void handleAppDiedLocked(ProcessRecord app,
5105            boolean restarting, boolean allowRestart) {
5106        int pid = app.pid;
5107        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5108                false /*replacingPid*/);
5109        if (!kept && !restarting) {
5110            removeLruProcessLocked(app);
5111            if (pid > 0) {
5112                ProcessList.remove(pid);
5113            }
5114        }
5115
5116        if (mProfileProc == app) {
5117            clearProfilerLocked();
5118        }
5119
5120        // Remove this application's activities from active lists.
5121        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5122
5123        app.activities.clear();
5124
5125        if (app.instrumentationClass != null) {
5126            Slog.w(TAG, "Crash of app " + app.processName
5127                  + " running instrumentation " + app.instrumentationClass);
5128            Bundle info = new Bundle();
5129            info.putString("shortMsg", "Process crashed.");
5130            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5131        }
5132
5133        if (!restarting && hasVisibleActivities
5134                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5135            // If there was nothing to resume, and we are not already restarting this process, but
5136            // there is a visible activity that is hosted by the process...  then make sure all
5137            // visible activities are running, taking care of restarting this process.
5138            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5139        }
5140    }
5141
5142    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5143        IBinder threadBinder = thread.asBinder();
5144        // Find the application record.
5145        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5146            ProcessRecord rec = mLruProcesses.get(i);
5147            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5148                return i;
5149            }
5150        }
5151        return -1;
5152    }
5153
5154    final ProcessRecord getRecordForAppLocked(
5155            IApplicationThread thread) {
5156        if (thread == null) {
5157            return null;
5158        }
5159
5160        int appIndex = getLRURecordIndexForAppLocked(thread);
5161        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5162    }
5163
5164    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5165        // If there are no longer any background processes running,
5166        // and the app that died was not running instrumentation,
5167        // then tell everyone we are now low on memory.
5168        boolean haveBg = false;
5169        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5170            ProcessRecord rec = mLruProcesses.get(i);
5171            if (rec.thread != null
5172                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5173                haveBg = true;
5174                break;
5175            }
5176        }
5177
5178        if (!haveBg) {
5179            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5180            if (doReport) {
5181                long now = SystemClock.uptimeMillis();
5182                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5183                    doReport = false;
5184                } else {
5185                    mLastMemUsageReportTime = now;
5186                }
5187            }
5188            final ArrayList<ProcessMemInfo> memInfos
5189                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5190            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5191            long now = SystemClock.uptimeMillis();
5192            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5193                ProcessRecord rec = mLruProcesses.get(i);
5194                if (rec == dyingProc || rec.thread == null) {
5195                    continue;
5196                }
5197                if (doReport) {
5198                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5199                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5200                }
5201                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5202                    // The low memory report is overriding any current
5203                    // state for a GC request.  Make sure to do
5204                    // heavy/important/visible/foreground processes first.
5205                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5206                        rec.lastRequestedGc = 0;
5207                    } else {
5208                        rec.lastRequestedGc = rec.lastLowMemory;
5209                    }
5210                    rec.reportLowMemory = true;
5211                    rec.lastLowMemory = now;
5212                    mProcessesToGc.remove(rec);
5213                    addProcessToGcListLocked(rec);
5214                }
5215            }
5216            if (doReport) {
5217                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5218                mHandler.sendMessage(msg);
5219            }
5220            scheduleAppGcsLocked();
5221        }
5222    }
5223
5224    final void appDiedLocked(ProcessRecord app) {
5225       appDiedLocked(app, app.pid, app.thread, false);
5226    }
5227
5228    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5229            boolean fromBinderDied) {
5230        // First check if this ProcessRecord is actually active for the pid.
5231        synchronized (mPidsSelfLocked) {
5232            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5233            if (curProc != app) {
5234                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5235                return;
5236            }
5237        }
5238
5239        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5240        synchronized (stats) {
5241            stats.noteProcessDiedLocked(app.info.uid, pid);
5242        }
5243
5244        if (!app.killed) {
5245            if (!fromBinderDied) {
5246                Process.killProcessQuiet(pid);
5247            }
5248            killProcessGroup(app.uid, pid);
5249            app.killed = true;
5250        }
5251
5252        // Clean up already done if the process has been re-started.
5253        if (app.pid == pid && app.thread != null &&
5254                app.thread.asBinder() == thread.asBinder()) {
5255            boolean doLowMem = app.instrumentationClass == null;
5256            boolean doOomAdj = doLowMem;
5257            if (!app.killedByAm) {
5258                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5259                        + ") has died");
5260                mAllowLowerMemLevel = true;
5261            } else {
5262                // Note that we always want to do oom adj to update our state with the
5263                // new number of procs.
5264                mAllowLowerMemLevel = false;
5265                doLowMem = false;
5266            }
5267            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5268            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5269                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5270            handleAppDiedLocked(app, false, true);
5271
5272            if (doOomAdj) {
5273                updateOomAdjLocked();
5274            }
5275            if (doLowMem) {
5276                doLowMemReportIfNeededLocked(app);
5277            }
5278        } else if (app.pid != pid) {
5279            // A new process has already been started.
5280            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5281                    + ") has died and restarted (pid " + app.pid + ").");
5282            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5283        } else if (DEBUG_PROCESSES) {
5284            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5285                    + thread.asBinder());
5286        }
5287    }
5288
5289    /**
5290     * If a stack trace dump file is configured, dump process stack traces.
5291     * @param clearTraces causes the dump file to be erased prior to the new
5292     *    traces being written, if true; when false, the new traces will be
5293     *    appended to any existing file content.
5294     * @param firstPids of dalvik VM processes to dump stack traces for first
5295     * @param lastPids of dalvik VM processes to dump stack traces for last
5296     * @param nativeProcs optional list of native process names to dump stack crawls
5297     * @return file containing stack traces, or null if no dump file is configured
5298     */
5299    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5300            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5301        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5302        if (tracesPath == null || tracesPath.length() == 0) {
5303            return null;
5304        }
5305
5306        File tracesFile = new File(tracesPath);
5307        try {
5308            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5309            tracesFile.createNewFile();
5310            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311        } catch (IOException e) {
5312            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5313            return null;
5314        }
5315
5316        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5317        return tracesFile;
5318    }
5319
5320    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5321            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5322        // Use a FileObserver to detect when traces finish writing.
5323        // The order of traces is considered important to maintain for legibility.
5324        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5325            @Override
5326            public synchronized void onEvent(int event, String path) { notify(); }
5327        };
5328
5329        try {
5330            observer.startWatching();
5331
5332            // First collect all of the stacks of the most important pids.
5333            if (firstPids != null) {
5334                try {
5335                    int num = firstPids.size();
5336                    for (int i = 0; i < num; i++) {
5337                        synchronized (observer) {
5338                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5339                                    + firstPids.get(i));
5340                            final long sime = SystemClock.elapsedRealtime();
5341                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5342                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5343                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5344                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5345                        }
5346                    }
5347                } catch (InterruptedException e) {
5348                    Slog.wtf(TAG, e);
5349                }
5350            }
5351
5352            // Next collect the stacks of the native pids
5353            if (nativeProcs != null) {
5354                int[] pids = Process.getPidsForCommands(nativeProcs);
5355                if (pids != null) {
5356                    for (int pid : pids) {
5357                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5358                        final long sime = SystemClock.elapsedRealtime();
5359                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5360                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5361                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5362                    }
5363                }
5364            }
5365
5366            // Lastly, measure CPU usage.
5367            if (processCpuTracker != null) {
5368                processCpuTracker.init();
5369                System.gc();
5370                processCpuTracker.update();
5371                try {
5372                    synchronized (processCpuTracker) {
5373                        processCpuTracker.wait(500); // measure over 1/2 second.
5374                    }
5375                } catch (InterruptedException e) {
5376                }
5377                processCpuTracker.update();
5378
5379                // We'll take the stack crawls of just the top apps using CPU.
5380                final int N = processCpuTracker.countWorkingStats();
5381                int numProcs = 0;
5382                for (int i=0; i<N && numProcs<5; i++) {
5383                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5384                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5385                        numProcs++;
5386                        try {
5387                            synchronized (observer) {
5388                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5389                                        + stats.pid);
5390                                final long stime = SystemClock.elapsedRealtime();
5391                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5392                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5393                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5394                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5395                            }
5396                        } catch (InterruptedException e) {
5397                            Slog.wtf(TAG, e);
5398                        }
5399                    } else if (DEBUG_ANR) {
5400                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5401                                + stats.pid);
5402                    }
5403                }
5404            }
5405        } finally {
5406            observer.stopWatching();
5407        }
5408    }
5409
5410    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5411        if (true || IS_USER_BUILD) {
5412            return;
5413        }
5414        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5415        if (tracesPath == null || tracesPath.length() == 0) {
5416            return;
5417        }
5418
5419        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5420        StrictMode.allowThreadDiskWrites();
5421        try {
5422            final File tracesFile = new File(tracesPath);
5423            final File tracesDir = tracesFile.getParentFile();
5424            final File tracesTmp = new File(tracesDir, "__tmp__");
5425            try {
5426                if (tracesFile.exists()) {
5427                    tracesTmp.delete();
5428                    tracesFile.renameTo(tracesTmp);
5429                }
5430                StringBuilder sb = new StringBuilder();
5431                Time tobj = new Time();
5432                tobj.set(System.currentTimeMillis());
5433                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5434                sb.append(": ");
5435                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5436                sb.append(" since ");
5437                sb.append(msg);
5438                FileOutputStream fos = new FileOutputStream(tracesFile);
5439                fos.write(sb.toString().getBytes());
5440                if (app == null) {
5441                    fos.write("\n*** No application process!".getBytes());
5442                }
5443                fos.close();
5444                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5445            } catch (IOException e) {
5446                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5447                return;
5448            }
5449
5450            if (app != null) {
5451                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5452                firstPids.add(app.pid);
5453                dumpStackTraces(tracesPath, firstPids, null, null, null);
5454            }
5455
5456            File lastTracesFile = null;
5457            File curTracesFile = null;
5458            for (int i=9; i>=0; i--) {
5459                String name = String.format(Locale.US, "slow%02d.txt", i);
5460                curTracesFile = new File(tracesDir, name);
5461                if (curTracesFile.exists()) {
5462                    if (lastTracesFile != null) {
5463                        curTracesFile.renameTo(lastTracesFile);
5464                    } else {
5465                        curTracesFile.delete();
5466                    }
5467                }
5468                lastTracesFile = curTracesFile;
5469            }
5470            tracesFile.renameTo(curTracesFile);
5471            if (tracesTmp.exists()) {
5472                tracesTmp.renameTo(tracesFile);
5473            }
5474        } finally {
5475            StrictMode.setThreadPolicy(oldPolicy);
5476        }
5477    }
5478
5479    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5480        if (!mLaunchWarningShown) {
5481            mLaunchWarningShown = true;
5482            mUiHandler.post(new Runnable() {
5483                @Override
5484                public void run() {
5485                    synchronized (ActivityManagerService.this) {
5486                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5487                        d.show();
5488                        mUiHandler.postDelayed(new Runnable() {
5489                            @Override
5490                            public void run() {
5491                                synchronized (ActivityManagerService.this) {
5492                                    d.dismiss();
5493                                    mLaunchWarningShown = false;
5494                                }
5495                            }
5496                        }, 4000);
5497                    }
5498                }
5499            });
5500        }
5501    }
5502
5503    @Override
5504    public boolean clearApplicationUserData(final String packageName,
5505            final IPackageDataObserver observer, int userId) {
5506        enforceNotIsolatedCaller("clearApplicationUserData");
5507        int uid = Binder.getCallingUid();
5508        int pid = Binder.getCallingPid();
5509        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5510                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5511
5512
5513        long callingId = Binder.clearCallingIdentity();
5514        try {
5515            IPackageManager pm = AppGlobals.getPackageManager();
5516            int pkgUid = -1;
5517            synchronized(this) {
5518                if (getPackageManagerInternalLocked().isPackageDataProtected(
5519                        userId, packageName)) {
5520                    throw new SecurityException(
5521                            "Cannot clear data for a protected package: " + packageName);
5522                }
5523
5524                try {
5525                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5526                } catch (RemoteException e) {
5527                }
5528                if (pkgUid == -1) {
5529                    Slog.w(TAG, "Invalid packageName: " + packageName);
5530                    if (observer != null) {
5531                        try {
5532                            observer.onRemoveCompleted(packageName, false);
5533                        } catch (RemoteException e) {
5534                            Slog.i(TAG, "Observer no longer exists.");
5535                        }
5536                    }
5537                    return false;
5538                }
5539                if (uid == pkgUid || checkComponentPermission(
5540                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5541                        pid, uid, -1, true)
5542                        == PackageManager.PERMISSION_GRANTED) {
5543                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5544                } else {
5545                    throw new SecurityException("PID " + pid + " does not have permission "
5546                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5547                                    + " of package " + packageName);
5548                }
5549
5550                // Remove all tasks match the cleared application package and user
5551                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5552                    final TaskRecord tr = mRecentTasks.get(i);
5553                    final String taskPackageName =
5554                            tr.getBaseIntent().getComponent().getPackageName();
5555                    if (tr.userId != userId) continue;
5556                    if (!taskPackageName.equals(packageName)) continue;
5557                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5558                }
5559            }
5560
5561            final int pkgUidF = pkgUid;
5562            final int userIdF = userId;
5563            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5564                @Override
5565                public void onRemoveCompleted(String packageName, boolean succeeded)
5566                        throws RemoteException {
5567                    synchronized (ActivityManagerService.this) {
5568                        finishForceStopPackageLocked(packageName, pkgUidF);
5569                    }
5570
5571                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5572                            Uri.fromParts("package", packageName, null));
5573                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5574                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5575                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5576                            null, null, 0, null, null, null, null, false, false, userIdF);
5577
5578                    if (observer != null) {
5579                        observer.onRemoveCompleted(packageName, succeeded);
5580                    }
5581                }
5582            };
5583
5584            try {
5585                // Clear application user data
5586                pm.clearApplicationUserData(packageName, localObserver, userId);
5587
5588                synchronized(this) {
5589                    // Remove all permissions granted from/to this package
5590                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5591                }
5592
5593                // Remove all zen rules created by this package; revoke it's zen access.
5594                INotificationManager inm = NotificationManager.getService();
5595                inm.removeAutomaticZenRules(packageName);
5596                inm.setNotificationPolicyAccessGranted(packageName, false);
5597
5598            } catch (RemoteException e) {
5599            }
5600        } finally {
5601            Binder.restoreCallingIdentity(callingId);
5602        }
5603        return true;
5604    }
5605
5606    @Override
5607    public void killBackgroundProcesses(final String packageName, int userId) {
5608        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5609                != PackageManager.PERMISSION_GRANTED &&
5610                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5611                        != PackageManager.PERMISSION_GRANTED) {
5612            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5613                    + Binder.getCallingPid()
5614                    + ", uid=" + Binder.getCallingUid()
5615                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5616            Slog.w(TAG, msg);
5617            throw new SecurityException(msg);
5618        }
5619
5620        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5621                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5622        long callingId = Binder.clearCallingIdentity();
5623        try {
5624            IPackageManager pm = AppGlobals.getPackageManager();
5625            synchronized(this) {
5626                int appId = -1;
5627                try {
5628                    appId = UserHandle.getAppId(
5629                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5630                } catch (RemoteException e) {
5631                }
5632                if (appId == -1) {
5633                    Slog.w(TAG, "Invalid packageName: " + packageName);
5634                    return;
5635                }
5636                killPackageProcessesLocked(packageName, appId, userId,
5637                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5638            }
5639        } finally {
5640            Binder.restoreCallingIdentity(callingId);
5641        }
5642    }
5643
5644    @Override
5645    public void killAllBackgroundProcesses() {
5646        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5647                != PackageManager.PERMISSION_GRANTED) {
5648            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5649                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5650                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5651            Slog.w(TAG, msg);
5652            throw new SecurityException(msg);
5653        }
5654
5655        final long callingId = Binder.clearCallingIdentity();
5656        try {
5657            synchronized (this) {
5658                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5659                final int NP = mProcessNames.getMap().size();
5660                for (int ip = 0; ip < NP; ip++) {
5661                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5662                    final int NA = apps.size();
5663                    for (int ia = 0; ia < NA; ia++) {
5664                        final ProcessRecord app = apps.valueAt(ia);
5665                        if (app.persistent) {
5666                            // We don't kill persistent processes.
5667                            continue;
5668                        }
5669                        if (app.removed) {
5670                            procs.add(app);
5671                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5672                            app.removed = true;
5673                            procs.add(app);
5674                        }
5675                    }
5676                }
5677
5678                final int N = procs.size();
5679                for (int i = 0; i < N; i++) {
5680                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5681                }
5682
5683                mAllowLowerMemLevel = true;
5684
5685                updateOomAdjLocked();
5686                doLowMemReportIfNeededLocked(null);
5687            }
5688        } finally {
5689            Binder.restoreCallingIdentity(callingId);
5690        }
5691    }
5692
5693    /**
5694     * Kills all background processes, except those matching any of the
5695     * specified properties.
5696     *
5697     * @param minTargetSdk the target SDK version at or above which to preserve
5698     *                     processes, or {@code -1} to ignore the target SDK
5699     * @param maxProcState the process state at or below which to preserve
5700     *                     processes, or {@code -1} to ignore the process state
5701     */
5702    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5703        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5704                != PackageManager.PERMISSION_GRANTED) {
5705            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5706                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5707                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5708            Slog.w(TAG, msg);
5709            throw new SecurityException(msg);
5710        }
5711
5712        final long callingId = Binder.clearCallingIdentity();
5713        try {
5714            synchronized (this) {
5715                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5716                final int NP = mProcessNames.getMap().size();
5717                for (int ip = 0; ip < NP; ip++) {
5718                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5719                    final int NA = apps.size();
5720                    for (int ia = 0; ia < NA; ia++) {
5721                        final ProcessRecord app = apps.valueAt(ia);
5722                        if (app.removed) {
5723                            procs.add(app);
5724                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5725                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5726                            app.removed = true;
5727                            procs.add(app);
5728                        }
5729                    }
5730                }
5731
5732                final int N = procs.size();
5733                for (int i = 0; i < N; i++) {
5734                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5735                }
5736            }
5737        } finally {
5738            Binder.restoreCallingIdentity(callingId);
5739        }
5740    }
5741
5742    @Override
5743    public void forceStopPackage(final String packageName, int userId) {
5744        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5745                != PackageManager.PERMISSION_GRANTED) {
5746            String msg = "Permission Denial: forceStopPackage() from pid="
5747                    + Binder.getCallingPid()
5748                    + ", uid=" + Binder.getCallingUid()
5749                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5750            Slog.w(TAG, msg);
5751            throw new SecurityException(msg);
5752        }
5753        final int callingPid = Binder.getCallingPid();
5754        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5755                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5756        long callingId = Binder.clearCallingIdentity();
5757        try {
5758            IPackageManager pm = AppGlobals.getPackageManager();
5759            synchronized(this) {
5760                int[] users = userId == UserHandle.USER_ALL
5761                        ? mUserController.getUsers() : new int[] { userId };
5762                for (int user : users) {
5763                    int pkgUid = -1;
5764                    try {
5765                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5766                                user);
5767                    } catch (RemoteException e) {
5768                    }
5769                    if (pkgUid == -1) {
5770                        Slog.w(TAG, "Invalid packageName: " + packageName);
5771                        continue;
5772                    }
5773                    try {
5774                        pm.setPackageStoppedState(packageName, true, user);
5775                    } catch (RemoteException e) {
5776                    } catch (IllegalArgumentException e) {
5777                        Slog.w(TAG, "Failed trying to unstop package "
5778                                + packageName + ": " + e);
5779                    }
5780                    if (mUserController.isUserRunningLocked(user, 0)) {
5781                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5782                        finishForceStopPackageLocked(packageName, pkgUid);
5783                    }
5784                }
5785            }
5786        } finally {
5787            Binder.restoreCallingIdentity(callingId);
5788        }
5789    }
5790
5791    @Override
5792    public void addPackageDependency(String packageName) {
5793        synchronized (this) {
5794            int callingPid = Binder.getCallingPid();
5795            if (callingPid == Process.myPid()) {
5796                //  Yeah, um, no.
5797                return;
5798            }
5799            ProcessRecord proc;
5800            synchronized (mPidsSelfLocked) {
5801                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5802            }
5803            if (proc != null) {
5804                if (proc.pkgDeps == null) {
5805                    proc.pkgDeps = new ArraySet<String>(1);
5806                }
5807                proc.pkgDeps.add(packageName);
5808            }
5809        }
5810    }
5811
5812    /*
5813     * The pkg name and app id have to be specified.
5814     */
5815    @Override
5816    public void killApplication(String pkg, int appId, int userId, String reason) {
5817        if (pkg == null) {
5818            return;
5819        }
5820        // Make sure the uid is valid.
5821        if (appId < 0) {
5822            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5823            return;
5824        }
5825        int callerUid = Binder.getCallingUid();
5826        // Only the system server can kill an application
5827        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5828            // Post an aysnc message to kill the application
5829            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5830            msg.arg1 = appId;
5831            msg.arg2 = userId;
5832            Bundle bundle = new Bundle();
5833            bundle.putString("pkg", pkg);
5834            bundle.putString("reason", reason);
5835            msg.obj = bundle;
5836            mHandler.sendMessage(msg);
5837        } else {
5838            throw new SecurityException(callerUid + " cannot kill pkg: " +
5839                    pkg);
5840        }
5841    }
5842
5843    @Override
5844    public void closeSystemDialogs(String reason) {
5845        enforceNotIsolatedCaller("closeSystemDialogs");
5846
5847        final int pid = Binder.getCallingPid();
5848        final int uid = Binder.getCallingUid();
5849        final long origId = Binder.clearCallingIdentity();
5850        try {
5851            synchronized (this) {
5852                // Only allow this from foreground processes, so that background
5853                // applications can't abuse it to prevent system UI from being shown.
5854                if (uid >= Process.FIRST_APPLICATION_UID) {
5855                    ProcessRecord proc;
5856                    synchronized (mPidsSelfLocked) {
5857                        proc = mPidsSelfLocked.get(pid);
5858                    }
5859                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5860                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5861                                + " from background process " + proc);
5862                        return;
5863                    }
5864                }
5865                closeSystemDialogsLocked(reason);
5866            }
5867        } finally {
5868            Binder.restoreCallingIdentity(origId);
5869        }
5870    }
5871
5872    void closeSystemDialogsLocked(String reason) {
5873        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5874        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5875                | Intent.FLAG_RECEIVER_FOREGROUND);
5876        if (reason != null) {
5877            intent.putExtra("reason", reason);
5878        }
5879        mWindowManager.closeSystemDialogs(reason);
5880
5881        mStackSupervisor.closeSystemDialogsLocked();
5882
5883        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5884                AppOpsManager.OP_NONE, null, false, false,
5885                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5886    }
5887
5888    @Override
5889    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5890        enforceNotIsolatedCaller("getProcessMemoryInfo");
5891        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5892        for (int i=pids.length-1; i>=0; i--) {
5893            ProcessRecord proc;
5894            int oomAdj;
5895            synchronized (this) {
5896                synchronized (mPidsSelfLocked) {
5897                    proc = mPidsSelfLocked.get(pids[i]);
5898                    oomAdj = proc != null ? proc.setAdj : 0;
5899                }
5900            }
5901            infos[i] = new Debug.MemoryInfo();
5902            Debug.getMemoryInfo(pids[i], infos[i]);
5903            if (proc != null) {
5904                synchronized (this) {
5905                    if (proc.thread != null && proc.setAdj == oomAdj) {
5906                        // Record this for posterity if the process has been stable.
5907                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5908                                infos[i].getTotalUss(), false, proc.pkgList);
5909                    }
5910                }
5911            }
5912        }
5913        return infos;
5914    }
5915
5916    @Override
5917    public long[] getProcessPss(int[] pids) {
5918        enforceNotIsolatedCaller("getProcessPss");
5919        long[] pss = new long[pids.length];
5920        for (int i=pids.length-1; i>=0; i--) {
5921            ProcessRecord proc;
5922            int oomAdj;
5923            synchronized (this) {
5924                synchronized (mPidsSelfLocked) {
5925                    proc = mPidsSelfLocked.get(pids[i]);
5926                    oomAdj = proc != null ? proc.setAdj : 0;
5927                }
5928            }
5929            long[] tmpUss = new long[1];
5930            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5931            if (proc != null) {
5932                synchronized (this) {
5933                    if (proc.thread != null && proc.setAdj == oomAdj) {
5934                        // Record this for posterity if the process has been stable.
5935                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5936                    }
5937                }
5938            }
5939        }
5940        return pss;
5941    }
5942
5943    @Override
5944    public void killApplicationProcess(String processName, int uid) {
5945        if (processName == null) {
5946            return;
5947        }
5948
5949        int callerUid = Binder.getCallingUid();
5950        // Only the system server can kill an application
5951        if (callerUid == Process.SYSTEM_UID) {
5952            synchronized (this) {
5953                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5954                if (app != null && app.thread != null) {
5955                    try {
5956                        app.thread.scheduleSuicide();
5957                    } catch (RemoteException e) {
5958                        // If the other end already died, then our work here is done.
5959                    }
5960                } else {
5961                    Slog.w(TAG, "Process/uid not found attempting kill of "
5962                            + processName + " / " + uid);
5963                }
5964            }
5965        } else {
5966            throw new SecurityException(callerUid + " cannot kill app process: " +
5967                    processName);
5968        }
5969    }
5970
5971    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5972        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5973                false, true, false, false, UserHandle.getUserId(uid), reason);
5974    }
5975
5976    private void finishForceStopPackageLocked(final String packageName, int uid) {
5977        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5978                Uri.fromParts("package", packageName, null));
5979        if (!mProcessesReady) {
5980            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5981                    | Intent.FLAG_RECEIVER_FOREGROUND);
5982        }
5983        intent.putExtra(Intent.EXTRA_UID, uid);
5984        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5985        broadcastIntentLocked(null, null, intent,
5986                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5987                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5988    }
5989
5990
5991    private final boolean killPackageProcessesLocked(String packageName, int appId,
5992            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5993            boolean doit, boolean evenPersistent, String reason) {
5994        ArrayList<ProcessRecord> procs = new ArrayList<>();
5995
5996        // Remove all processes this package may have touched: all with the
5997        // same UID (except for the system or root user), and all whose name
5998        // matches the package name.
5999        final int NP = mProcessNames.getMap().size();
6000        for (int ip=0; ip<NP; ip++) {
6001            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6002            final int NA = apps.size();
6003            for (int ia=0; ia<NA; ia++) {
6004                ProcessRecord app = apps.valueAt(ia);
6005                if (app.persistent && !evenPersistent) {
6006                    // we don't kill persistent processes
6007                    continue;
6008                }
6009                if (app.removed) {
6010                    if (doit) {
6011                        procs.add(app);
6012                    }
6013                    continue;
6014                }
6015
6016                // Skip process if it doesn't meet our oom adj requirement.
6017                if (app.setAdj < minOomAdj) {
6018                    continue;
6019                }
6020
6021                // If no package is specified, we call all processes under the
6022                // give user id.
6023                if (packageName == null) {
6024                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6025                        continue;
6026                    }
6027                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6028                        continue;
6029                    }
6030                // Package has been specified, we want to hit all processes
6031                // that match it.  We need to qualify this by the processes
6032                // that are running under the specified app and user ID.
6033                } else {
6034                    final boolean isDep = app.pkgDeps != null
6035                            && app.pkgDeps.contains(packageName);
6036                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6037                        continue;
6038                    }
6039                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6040                        continue;
6041                    }
6042                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6043                        continue;
6044                    }
6045                }
6046
6047                // Process has passed all conditions, kill it!
6048                if (!doit) {
6049                    return true;
6050                }
6051                app.removed = true;
6052                procs.add(app);
6053            }
6054        }
6055
6056        int N = procs.size();
6057        for (int i=0; i<N; i++) {
6058            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6059        }
6060        updateOomAdjLocked();
6061        return N > 0;
6062    }
6063
6064    private void cleanupDisabledPackageComponentsLocked(
6065            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6066
6067        Set<String> disabledClasses = null;
6068        boolean packageDisabled = false;
6069        IPackageManager pm = AppGlobals.getPackageManager();
6070
6071        if (changedClasses == null) {
6072            // Nothing changed...
6073            return;
6074        }
6075
6076        // Determine enable/disable state of the package and its components.
6077        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6078        for (int i = changedClasses.length - 1; i >= 0; i--) {
6079            final String changedClass = changedClasses[i];
6080
6081            if (changedClass.equals(packageName)) {
6082                try {
6083                    // Entire package setting changed
6084                    enabled = pm.getApplicationEnabledSetting(packageName,
6085                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6086                } catch (Exception e) {
6087                    // No such package/component; probably racing with uninstall.  In any
6088                    // event it means we have nothing further to do here.
6089                    return;
6090                }
6091                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6092                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6093                if (packageDisabled) {
6094                    // Entire package is disabled.
6095                    // No need to continue to check component states.
6096                    disabledClasses = null;
6097                    break;
6098                }
6099            } else {
6100                try {
6101                    enabled = pm.getComponentEnabledSetting(
6102                            new ComponentName(packageName, changedClass),
6103                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6104                } catch (Exception e) {
6105                    // As above, probably racing with uninstall.
6106                    return;
6107                }
6108                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6109                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6110                    if (disabledClasses == null) {
6111                        disabledClasses = new ArraySet<>(changedClasses.length);
6112                    }
6113                    disabledClasses.add(changedClass);
6114                }
6115            }
6116        }
6117
6118        if (!packageDisabled && disabledClasses == null) {
6119            // Nothing to do here...
6120            return;
6121        }
6122
6123        // Clean-up disabled activities.
6124        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6125                packageName, disabledClasses, true, false, userId) && mBooted) {
6126            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6127            mStackSupervisor.scheduleIdleLocked();
6128        }
6129
6130        // Clean-up disabled tasks
6131        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6132
6133        // Clean-up disabled services.
6134        mServices.bringDownDisabledPackageServicesLocked(
6135                packageName, disabledClasses, userId, false, killProcess, true);
6136
6137        // Clean-up disabled providers.
6138        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6139        mProviderMap.collectPackageProvidersLocked(
6140                packageName, disabledClasses, true, false, userId, providers);
6141        for (int i = providers.size() - 1; i >= 0; i--) {
6142            removeDyingProviderLocked(null, providers.get(i), true);
6143        }
6144
6145        // Clean-up disabled broadcast receivers.
6146        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6147            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6148                    packageName, disabledClasses, userId, true);
6149        }
6150
6151    }
6152
6153    final boolean clearBroadcastQueueForUserLocked(int userId) {
6154        boolean didSomething = false;
6155        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6156            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6157                    null, null, userId, true);
6158        }
6159        return didSomething;
6160    }
6161
6162    final boolean forceStopPackageLocked(String packageName, int appId,
6163            boolean callerWillRestart, boolean purgeCache, boolean doit,
6164            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6165        int i;
6166
6167        if (userId == UserHandle.USER_ALL && packageName == null) {
6168            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6169        }
6170
6171        if (appId < 0 && packageName != null) {
6172            try {
6173                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6174                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6175            } catch (RemoteException e) {
6176            }
6177        }
6178
6179        if (doit) {
6180            if (packageName != null) {
6181                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6182                        + " user=" + userId + ": " + reason);
6183            } else {
6184                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6185            }
6186
6187            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6188        }
6189
6190        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6191                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6192                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6193
6194        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6195
6196        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6197                packageName, null, doit, evenPersistent, userId)) {
6198            if (!doit) {
6199                return true;
6200            }
6201            didSomething = true;
6202        }
6203
6204        if (mServices.bringDownDisabledPackageServicesLocked(
6205                packageName, null, userId, evenPersistent, true, doit)) {
6206            if (!doit) {
6207                return true;
6208            }
6209            didSomething = true;
6210        }
6211
6212        if (packageName == null) {
6213            // Remove all sticky broadcasts from this user.
6214            mStickyBroadcasts.remove(userId);
6215        }
6216
6217        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6218        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6219                userId, providers)) {
6220            if (!doit) {
6221                return true;
6222            }
6223            didSomething = true;
6224        }
6225        for (i = providers.size() - 1; i >= 0; i--) {
6226            removeDyingProviderLocked(null, providers.get(i), true);
6227        }
6228
6229        // Remove transient permissions granted from/to this package/user
6230        removeUriPermissionsForPackageLocked(packageName, userId, false);
6231
6232        if (doit) {
6233            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6234                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6235                        packageName, null, userId, doit);
6236            }
6237        }
6238
6239        if (packageName == null || uninstalling) {
6240            // Remove pending intents.  For now we only do this when force
6241            // stopping users, because we have some problems when doing this
6242            // for packages -- app widgets are not currently cleaned up for
6243            // such packages, so they can be left with bad pending intents.
6244            if (mIntentSenderRecords.size() > 0) {
6245                Iterator<WeakReference<PendingIntentRecord>> it
6246                        = mIntentSenderRecords.values().iterator();
6247                while (it.hasNext()) {
6248                    WeakReference<PendingIntentRecord> wpir = it.next();
6249                    if (wpir == null) {
6250                        it.remove();
6251                        continue;
6252                    }
6253                    PendingIntentRecord pir = wpir.get();
6254                    if (pir == null) {
6255                        it.remove();
6256                        continue;
6257                    }
6258                    if (packageName == null) {
6259                        // Stopping user, remove all objects for the user.
6260                        if (pir.key.userId != userId) {
6261                            // Not the same user, skip it.
6262                            continue;
6263                        }
6264                    } else {
6265                        if (UserHandle.getAppId(pir.uid) != appId) {
6266                            // Different app id, skip it.
6267                            continue;
6268                        }
6269                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6270                            // Different user, skip it.
6271                            continue;
6272                        }
6273                        if (!pir.key.packageName.equals(packageName)) {
6274                            // Different package, skip it.
6275                            continue;
6276                        }
6277                    }
6278                    if (!doit) {
6279                        return true;
6280                    }
6281                    didSomething = true;
6282                    it.remove();
6283                    pir.canceled = true;
6284                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6285                        pir.key.activity.pendingResults.remove(pir.ref);
6286                    }
6287                }
6288            }
6289        }
6290
6291        if (doit) {
6292            if (purgeCache && packageName != null) {
6293                AttributeCache ac = AttributeCache.instance();
6294                if (ac != null) {
6295                    ac.removePackage(packageName);
6296                }
6297            }
6298            if (mBooted) {
6299                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6300                mStackSupervisor.scheduleIdleLocked();
6301            }
6302        }
6303
6304        return didSomething;
6305    }
6306
6307    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6308        return removeProcessNameLocked(name, uid, null);
6309    }
6310
6311    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6312            final ProcessRecord expecting) {
6313        ProcessRecord old = mProcessNames.get(name, uid);
6314        // Only actually remove when the currently recorded value matches the
6315        // record that we expected; if it doesn't match then we raced with a
6316        // newly created process and we don't want to destroy the new one.
6317        if ((expecting == null) || (old == expecting)) {
6318            mProcessNames.remove(name, uid);
6319        }
6320        if (old != null && old.uidRecord != null) {
6321            old.uidRecord.numProcs--;
6322            if (old.uidRecord.numProcs == 0) {
6323                // No more processes using this uid, tell clients it is gone.
6324                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6325                        "No more processes in " + old.uidRecord);
6326                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6327                mActiveUids.remove(uid);
6328                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6329            }
6330            old.uidRecord = null;
6331        }
6332        mIsolatedProcesses.remove(uid);
6333        return old;
6334    }
6335
6336    private final void addProcessNameLocked(ProcessRecord proc) {
6337        // We shouldn't already have a process under this name, but just in case we
6338        // need to clean up whatever may be there now.
6339        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6340        if (old == proc && proc.persistent) {
6341            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6342            Slog.w(TAG, "Re-adding persistent process " + proc);
6343        } else if (old != null) {
6344            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6345        }
6346        UidRecord uidRec = mActiveUids.get(proc.uid);
6347        if (uidRec == null) {
6348            uidRec = new UidRecord(proc.uid);
6349            // This is the first appearance of the uid, report it now!
6350            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6351                    "Creating new process uid: " + uidRec);
6352            mActiveUids.put(proc.uid, uidRec);
6353            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6354            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6355        }
6356        proc.uidRecord = uidRec;
6357
6358        // Reset render thread tid if it was already set, so new process can set it again.
6359        proc.renderThreadTid = 0;
6360        uidRec.numProcs++;
6361        mProcessNames.put(proc.processName, proc.uid, proc);
6362        if (proc.isolated) {
6363            mIsolatedProcesses.put(proc.uid, proc);
6364        }
6365    }
6366
6367    boolean removeProcessLocked(ProcessRecord app,
6368            boolean callerWillRestart, boolean allowRestart, String reason) {
6369        final String name = app.processName;
6370        final int uid = app.uid;
6371        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6372            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6373
6374        ProcessRecord old = mProcessNames.get(name, uid);
6375        if (old != app) {
6376            // This process is no longer active, so nothing to do.
6377            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6378            return false;
6379        }
6380        removeProcessNameLocked(name, uid);
6381        if (mHeavyWeightProcess == app) {
6382            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6383                    mHeavyWeightProcess.userId, 0));
6384            mHeavyWeightProcess = null;
6385        }
6386        boolean needRestart = false;
6387        if (app.pid > 0 && app.pid != MY_PID) {
6388            int pid = app.pid;
6389            synchronized (mPidsSelfLocked) {
6390                mPidsSelfLocked.remove(pid);
6391                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6392            }
6393            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6394            if (app.isolated) {
6395                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6396            }
6397            boolean willRestart = false;
6398            if (app.persistent && !app.isolated) {
6399                if (!callerWillRestart) {
6400                    willRestart = true;
6401                } else {
6402                    needRestart = true;
6403                }
6404            }
6405            app.kill(reason, true);
6406            handleAppDiedLocked(app, willRestart, allowRestart);
6407            if (willRestart) {
6408                removeLruProcessLocked(app);
6409                addAppLocked(app.info, false, null /* ABI override */);
6410            }
6411        } else {
6412            mRemovedProcesses.add(app);
6413        }
6414
6415        return needRestart;
6416    }
6417
6418    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6419        cleanupAppInLaunchingProvidersLocked(app, true);
6420        removeProcessLocked(app, false, true, "timeout publishing content providers");
6421    }
6422
6423    private final void processStartTimedOutLocked(ProcessRecord app) {
6424        final int pid = app.pid;
6425        boolean gone = false;
6426        synchronized (mPidsSelfLocked) {
6427            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6428            if (knownApp != null && knownApp.thread == null) {
6429                mPidsSelfLocked.remove(pid);
6430                gone = true;
6431            }
6432        }
6433
6434        if (gone) {
6435            Slog.w(TAG, "Process " + app + " failed to attach");
6436            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6437                    pid, app.uid, app.processName);
6438            removeProcessNameLocked(app.processName, app.uid);
6439            if (mHeavyWeightProcess == app) {
6440                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6441                        mHeavyWeightProcess.userId, 0));
6442                mHeavyWeightProcess = null;
6443            }
6444            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6445            if (app.isolated) {
6446                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6447            }
6448            // Take care of any launching providers waiting for this process.
6449            cleanupAppInLaunchingProvidersLocked(app, true);
6450            // Take care of any services that are waiting for the process.
6451            mServices.processStartTimedOutLocked(app);
6452            app.kill("start timeout", true);
6453            removeLruProcessLocked(app);
6454            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6455                Slog.w(TAG, "Unattached app died before backup, skipping");
6456                mHandler.post(new Runnable() {
6457                @Override
6458                    public void run(){
6459                        try {
6460                            IBackupManager bm = IBackupManager.Stub.asInterface(
6461                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6462                            bm.agentDisconnected(app.info.packageName);
6463                        } catch (RemoteException e) {
6464                            // Can't happen; the backup manager is local
6465                        }
6466                    }
6467                });
6468            }
6469            if (isPendingBroadcastProcessLocked(pid)) {
6470                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6471                skipPendingBroadcastLocked(pid);
6472            }
6473        } else {
6474            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6475        }
6476    }
6477
6478    private final boolean attachApplicationLocked(IApplicationThread thread,
6479            int pid) {
6480
6481        // Find the application record that is being attached...  either via
6482        // the pid if we are running in multiple processes, or just pull the
6483        // next app record if we are emulating process with anonymous threads.
6484        ProcessRecord app;
6485        if (pid != MY_PID && pid >= 0) {
6486            synchronized (mPidsSelfLocked) {
6487                app = mPidsSelfLocked.get(pid);
6488            }
6489        } else {
6490            app = null;
6491        }
6492
6493        if (app == null) {
6494            Slog.w(TAG, "No pending application record for pid " + pid
6495                    + " (IApplicationThread " + thread + "); dropping process");
6496            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6497            if (pid > 0 && pid != MY_PID) {
6498                Process.killProcessQuiet(pid);
6499                //TODO: killProcessGroup(app.info.uid, pid);
6500            } else {
6501                try {
6502                    thread.scheduleExit();
6503                } catch (Exception e) {
6504                    // Ignore exceptions.
6505                }
6506            }
6507            return false;
6508        }
6509
6510        // If this application record is still attached to a previous
6511        // process, clean it up now.
6512        if (app.thread != null) {
6513            handleAppDiedLocked(app, true, true);
6514        }
6515
6516        // Tell the process all about itself.
6517
6518        if (DEBUG_ALL) Slog.v(
6519                TAG, "Binding process pid " + pid + " to record " + app);
6520
6521        final String processName = app.processName;
6522        try {
6523            AppDeathRecipient adr = new AppDeathRecipient(
6524                    app, pid, thread);
6525            thread.asBinder().linkToDeath(adr, 0);
6526            app.deathRecipient = adr;
6527        } catch (RemoteException e) {
6528            app.resetPackageList(mProcessStats);
6529            startProcessLocked(app, "link fail", processName);
6530            return false;
6531        }
6532
6533        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6534
6535        app.makeActive(thread, mProcessStats);
6536        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6537        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6538        app.forcingToForeground = null;
6539        updateProcessForegroundLocked(app, false, false);
6540        app.hasShownUi = false;
6541        app.debugging = false;
6542        app.cached = false;
6543        app.killedByAm = false;
6544        app.killed = false;
6545
6546
6547        // We carefully use the same state that PackageManager uses for
6548        // filtering, since we use this flag to decide if we need to install
6549        // providers when user is unlocked later
6550        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6551
6552        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6553
6554        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6555        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6556
6557        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6558            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6559            msg.obj = app;
6560            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6561        }
6562
6563        if (!normalMode) {
6564            Slog.i(TAG, "Launching preboot mode app: " + app);
6565        }
6566
6567        if (DEBUG_ALL) Slog.v(
6568            TAG, "New app record " + app
6569            + " thread=" + thread.asBinder() + " pid=" + pid);
6570        try {
6571            int testMode = IApplicationThread.DEBUG_OFF;
6572            if (mDebugApp != null && mDebugApp.equals(processName)) {
6573                testMode = mWaitForDebugger
6574                    ? IApplicationThread.DEBUG_WAIT
6575                    : IApplicationThread.DEBUG_ON;
6576                app.debugging = true;
6577                if (mDebugTransient) {
6578                    mDebugApp = mOrigDebugApp;
6579                    mWaitForDebugger = mOrigWaitForDebugger;
6580                }
6581            }
6582            String profileFile = app.instrumentationProfileFile;
6583            ParcelFileDescriptor profileFd = null;
6584            int samplingInterval = 0;
6585            boolean profileAutoStop = false;
6586            if (mProfileApp != null && mProfileApp.equals(processName)) {
6587                mProfileProc = app;
6588                profileFile = mProfileFile;
6589                profileFd = mProfileFd;
6590                samplingInterval = mSamplingInterval;
6591                profileAutoStop = mAutoStopProfiler;
6592            }
6593            boolean enableTrackAllocation = false;
6594            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6595                enableTrackAllocation = true;
6596                mTrackAllocationApp = null;
6597            }
6598
6599            // If the app is being launched for restore or full backup, set it up specially
6600            boolean isRestrictedBackupMode = false;
6601            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6602                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6603                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6604                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6605                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6606            }
6607
6608            if (app.instrumentationClass != null) {
6609                notifyPackageUse(app.instrumentationClass.getPackageName(),
6610                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6611            }
6612            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6613                    + processName + " with config " + mConfiguration);
6614            ApplicationInfo appInfo = app.instrumentationInfo != null
6615                    ? app.instrumentationInfo : app.info;
6616            app.compat = compatibilityInfoForPackageLocked(appInfo);
6617            if (profileFd != null) {
6618                profileFd = profileFd.dup();
6619            }
6620            ProfilerInfo profilerInfo = profileFile == null ? null
6621                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6622            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6623                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6624                    app.instrumentationUiAutomationConnection, testMode,
6625                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6626                    isRestrictedBackupMode || !normalMode, app.persistent,
6627                    new Configuration(mConfiguration), app.compat,
6628                    getCommonServicesLocked(app.isolated),
6629                    mCoreSettingsObserver.getCoreSettingsLocked());
6630            updateLruProcessLocked(app, false, null);
6631            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6632        } catch (Exception e) {
6633            // todo: Yikes!  What should we do?  For now we will try to
6634            // start another process, but that could easily get us in
6635            // an infinite loop of restarting processes...
6636            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6637
6638            app.resetPackageList(mProcessStats);
6639            app.unlinkDeathRecipient();
6640            startProcessLocked(app, "bind fail", processName);
6641            return false;
6642        }
6643
6644        // Remove this record from the list of starting applications.
6645        mPersistentStartingProcesses.remove(app);
6646        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6647                "Attach application locked removing on hold: " + app);
6648        mProcessesOnHold.remove(app);
6649
6650        boolean badApp = false;
6651        boolean didSomething = false;
6652
6653        // See if the top visible activity is waiting to run in this process...
6654        if (normalMode) {
6655            try {
6656                if (mStackSupervisor.attachApplicationLocked(app)) {
6657                    didSomething = true;
6658                }
6659            } catch (Exception e) {
6660                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6661                badApp = true;
6662            }
6663        }
6664
6665        // Find any services that should be running in this process...
6666        if (!badApp) {
6667            try {
6668                didSomething |= mServices.attachApplicationLocked(app, processName);
6669            } catch (Exception e) {
6670                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6671                badApp = true;
6672            }
6673        }
6674
6675        // Check if a next-broadcast receiver is in this process...
6676        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6677            try {
6678                didSomething |= sendPendingBroadcastsLocked(app);
6679            } catch (Exception e) {
6680                // If the app died trying to launch the receiver we declare it 'bad'
6681                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6682                badApp = true;
6683            }
6684        }
6685
6686        // Check whether the next backup agent is in this process...
6687        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6688            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6689                    "New app is backup target, launching agent for " + app);
6690            notifyPackageUse(mBackupTarget.appInfo.packageName,
6691                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6692            try {
6693                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6694                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6695                        mBackupTarget.backupMode);
6696            } catch (Exception e) {
6697                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6698                badApp = true;
6699            }
6700        }
6701
6702        if (badApp) {
6703            app.kill("error during init", true);
6704            handleAppDiedLocked(app, false, true);
6705            return false;
6706        }
6707
6708        if (!didSomething) {
6709            updateOomAdjLocked();
6710        }
6711
6712        return true;
6713    }
6714
6715    @Override
6716    public final void attachApplication(IApplicationThread thread) {
6717        synchronized (this) {
6718            int callingPid = Binder.getCallingPid();
6719            final long origId = Binder.clearCallingIdentity();
6720            attachApplicationLocked(thread, callingPid);
6721            Binder.restoreCallingIdentity(origId);
6722        }
6723    }
6724
6725    @Override
6726    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6727        final long origId = Binder.clearCallingIdentity();
6728        synchronized (this) {
6729            ActivityStack stack = ActivityRecord.getStackLocked(token);
6730            if (stack != null) {
6731                ActivityRecord r =
6732                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6733                if (stopProfiling) {
6734                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6735                        try {
6736                            mProfileFd.close();
6737                        } catch (IOException e) {
6738                        }
6739                        clearProfilerLocked();
6740                    }
6741                }
6742            }
6743        }
6744        Binder.restoreCallingIdentity(origId);
6745    }
6746
6747    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6748        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6749                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6750    }
6751
6752    void enableScreenAfterBoot() {
6753        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6754                SystemClock.uptimeMillis());
6755        mWindowManager.enableScreenAfterBoot();
6756
6757        synchronized (this) {
6758            updateEventDispatchingLocked();
6759        }
6760    }
6761
6762    @Override
6763    public void showBootMessage(final CharSequence msg, final boolean always) {
6764        if (Binder.getCallingUid() != Process.myUid()) {
6765            throw new SecurityException();
6766        }
6767        mWindowManager.showBootMessage(msg, always);
6768    }
6769
6770    @Override
6771    public void keyguardWaitingForActivityDrawn() {
6772        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6773        final long token = Binder.clearCallingIdentity();
6774        try {
6775            synchronized (this) {
6776                if (DEBUG_LOCKSCREEN) logLockScreen("");
6777                mWindowManager.keyguardWaitingForActivityDrawn();
6778                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6779                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6780                    updateSleepIfNeededLocked();
6781                }
6782            }
6783        } finally {
6784            Binder.restoreCallingIdentity(token);
6785        }
6786    }
6787
6788    @Override
6789    public void keyguardGoingAway(int flags) {
6790        enforceNotIsolatedCaller("keyguardGoingAway");
6791        final long token = Binder.clearCallingIdentity();
6792        try {
6793            synchronized (this) {
6794                if (DEBUG_LOCKSCREEN) logLockScreen("");
6795                mWindowManager.keyguardGoingAway(flags);
6796                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6797                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6798                    updateSleepIfNeededLocked();
6799
6800                    // Some stack visibility might change (e.g. docked stack)
6801                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6802                }
6803            }
6804        } finally {
6805            Binder.restoreCallingIdentity(token);
6806        }
6807    }
6808
6809    final void finishBooting() {
6810        synchronized (this) {
6811            if (!mBootAnimationComplete) {
6812                mCallFinishBooting = true;
6813                return;
6814            }
6815            mCallFinishBooting = false;
6816        }
6817
6818        ArraySet<String> completedIsas = new ArraySet<String>();
6819        for (String abi : Build.SUPPORTED_ABIS) {
6820            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6821            final String instructionSet = VMRuntime.getInstructionSet(abi);
6822            if (!completedIsas.contains(instructionSet)) {
6823                try {
6824                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6825                } catch (InstallerException e) {
6826                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6827                            e.getMessage() +")");
6828                }
6829                completedIsas.add(instructionSet);
6830            }
6831        }
6832
6833        IntentFilter pkgFilter = new IntentFilter();
6834        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6835        pkgFilter.addDataScheme("package");
6836        mContext.registerReceiver(new BroadcastReceiver() {
6837            @Override
6838            public void onReceive(Context context, Intent intent) {
6839                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6840                if (pkgs != null) {
6841                    for (String pkg : pkgs) {
6842                        synchronized (ActivityManagerService.this) {
6843                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6844                                    0, "query restart")) {
6845                                setResultCode(Activity.RESULT_OK);
6846                                return;
6847                            }
6848                        }
6849                    }
6850                }
6851            }
6852        }, pkgFilter);
6853
6854        IntentFilter dumpheapFilter = new IntentFilter();
6855        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6856        mContext.registerReceiver(new BroadcastReceiver() {
6857            @Override
6858            public void onReceive(Context context, Intent intent) {
6859                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6860                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6861                } else {
6862                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6863                }
6864            }
6865        }, dumpheapFilter);
6866
6867        // Let system services know.
6868        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6869
6870        synchronized (this) {
6871            // Ensure that any processes we had put on hold are now started
6872            // up.
6873            final int NP = mProcessesOnHold.size();
6874            if (NP > 0) {
6875                ArrayList<ProcessRecord> procs =
6876                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6877                for (int ip=0; ip<NP; ip++) {
6878                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6879                            + procs.get(ip));
6880                    startProcessLocked(procs.get(ip), "on-hold", null);
6881                }
6882            }
6883
6884            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6885                // Start looking for apps that are abusing wake locks.
6886                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6887                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6888                // Tell anyone interested that we are done booting!
6889                SystemProperties.set("sys.boot_completed", "1");
6890
6891                // And trigger dev.bootcomplete if we are not showing encryption progress
6892                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6893                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6894                    SystemProperties.set("dev.bootcomplete", "1");
6895                }
6896                mUserController.sendBootCompletedLocked(
6897                        new IIntentReceiver.Stub() {
6898                            @Override
6899                            public void performReceive(Intent intent, int resultCode,
6900                                    String data, Bundle extras, boolean ordered,
6901                                    boolean sticky, int sendingUser) {
6902                                synchronized (ActivityManagerService.this) {
6903                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6904                                            true, false);
6905                                }
6906                            }
6907                        });
6908                scheduleStartProfilesLocked();
6909            }
6910        }
6911    }
6912
6913    @Override
6914    public void bootAnimationComplete() {
6915        final boolean callFinishBooting;
6916        synchronized (this) {
6917            callFinishBooting = mCallFinishBooting;
6918            mBootAnimationComplete = true;
6919        }
6920        if (callFinishBooting) {
6921            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6922            finishBooting();
6923            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6924        }
6925    }
6926
6927    final void ensureBootCompleted() {
6928        boolean booting;
6929        boolean enableScreen;
6930        synchronized (this) {
6931            booting = mBooting;
6932            mBooting = false;
6933            enableScreen = !mBooted;
6934            mBooted = true;
6935        }
6936
6937        if (booting) {
6938            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6939            finishBooting();
6940            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6941        }
6942
6943        if (enableScreen) {
6944            enableScreenAfterBoot();
6945        }
6946    }
6947
6948    @Override
6949    public final void activityResumed(IBinder token) {
6950        final long origId = Binder.clearCallingIdentity();
6951        synchronized(this) {
6952            ActivityStack stack = ActivityRecord.getStackLocked(token);
6953            if (stack != null) {
6954                stack.activityResumedLocked(token);
6955            }
6956        }
6957        Binder.restoreCallingIdentity(origId);
6958    }
6959
6960    @Override
6961    public final void activityPaused(IBinder token) {
6962        final long origId = Binder.clearCallingIdentity();
6963        synchronized(this) {
6964            ActivityStack stack = ActivityRecord.getStackLocked(token);
6965            if (stack != null) {
6966                stack.activityPausedLocked(token, false);
6967            }
6968        }
6969        Binder.restoreCallingIdentity(origId);
6970    }
6971
6972    @Override
6973    public final void activityStopped(IBinder token, Bundle icicle,
6974            PersistableBundle persistentState, CharSequence description) {
6975        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6976
6977        // Refuse possible leaked file descriptors
6978        if (icicle != null && icicle.hasFileDescriptors()) {
6979            throw new IllegalArgumentException("File descriptors passed in Bundle");
6980        }
6981
6982        final long origId = Binder.clearCallingIdentity();
6983
6984        synchronized (this) {
6985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6986            if (r != null) {
6987                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6988            }
6989        }
6990
6991        trimApplications();
6992
6993        Binder.restoreCallingIdentity(origId);
6994    }
6995
6996    @Override
6997    public final void activityDestroyed(IBinder token) {
6998        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6999        synchronized (this) {
7000            ActivityStack stack = ActivityRecord.getStackLocked(token);
7001            if (stack != null) {
7002                stack.activityDestroyedLocked(token, "activityDestroyed");
7003            }
7004        }
7005    }
7006
7007    @Override
7008    public final void activityRelaunched(IBinder token) {
7009        final long origId = Binder.clearCallingIdentity();
7010        synchronized (this) {
7011            mStackSupervisor.activityRelaunchedLocked(token);
7012        }
7013        Binder.restoreCallingIdentity(origId);
7014    }
7015
7016    @Override
7017    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7018            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7019        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7020                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7021        synchronized (this) {
7022            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7023            if (record == null) {
7024                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7025                        + "found for: " + token);
7026            }
7027            record.setSizeConfigurations(horizontalSizeConfiguration,
7028                    verticalSizeConfigurations, smallestSizeConfigurations);
7029        }
7030    }
7031
7032    @Override
7033    public final void backgroundResourcesReleased(IBinder token) {
7034        final long origId = Binder.clearCallingIdentity();
7035        try {
7036            synchronized (this) {
7037                ActivityStack stack = ActivityRecord.getStackLocked(token);
7038                if (stack != null) {
7039                    stack.backgroundResourcesReleased();
7040                }
7041            }
7042        } finally {
7043            Binder.restoreCallingIdentity(origId);
7044        }
7045    }
7046
7047    @Override
7048    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7049        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7050    }
7051
7052    @Override
7053    public final void notifyEnterAnimationComplete(IBinder token) {
7054        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7055    }
7056
7057    @Override
7058    public String getCallingPackage(IBinder token) {
7059        synchronized (this) {
7060            ActivityRecord r = getCallingRecordLocked(token);
7061            return r != null ? r.info.packageName : null;
7062        }
7063    }
7064
7065    @Override
7066    public ComponentName getCallingActivity(IBinder token) {
7067        synchronized (this) {
7068            ActivityRecord r = getCallingRecordLocked(token);
7069            return r != null ? r.intent.getComponent() : null;
7070        }
7071    }
7072
7073    private ActivityRecord getCallingRecordLocked(IBinder token) {
7074        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7075        if (r == null) {
7076            return null;
7077        }
7078        return r.resultTo;
7079    }
7080
7081    @Override
7082    public ComponentName getActivityClassForToken(IBinder token) {
7083        synchronized(this) {
7084            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7085            if (r == null) {
7086                return null;
7087            }
7088            return r.intent.getComponent();
7089        }
7090    }
7091
7092    @Override
7093    public String getPackageForToken(IBinder token) {
7094        synchronized(this) {
7095            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7096            if (r == null) {
7097                return null;
7098            }
7099            return r.packageName;
7100        }
7101    }
7102
7103    @Override
7104    public boolean isRootVoiceInteraction(IBinder token) {
7105        synchronized(this) {
7106            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7107            if (r == null) {
7108                return false;
7109            }
7110            return r.rootVoiceInteraction;
7111        }
7112    }
7113
7114    @Override
7115    public IIntentSender getIntentSender(int type,
7116            String packageName, IBinder token, String resultWho,
7117            int requestCode, Intent[] intents, String[] resolvedTypes,
7118            int flags, Bundle bOptions, int userId) {
7119        enforceNotIsolatedCaller("getIntentSender");
7120        // Refuse possible leaked file descriptors
7121        if (intents != null) {
7122            if (intents.length < 1) {
7123                throw new IllegalArgumentException("Intents array length must be >= 1");
7124            }
7125            for (int i=0; i<intents.length; i++) {
7126                Intent intent = intents[i];
7127                if (intent != null) {
7128                    if (intent.hasFileDescriptors()) {
7129                        throw new IllegalArgumentException("File descriptors passed in Intent");
7130                    }
7131                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7132                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7133                        throw new IllegalArgumentException(
7134                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7135                    }
7136                    intents[i] = new Intent(intent);
7137                }
7138            }
7139            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7140                throw new IllegalArgumentException(
7141                        "Intent array length does not match resolvedTypes length");
7142            }
7143        }
7144        if (bOptions != null) {
7145            if (bOptions.hasFileDescriptors()) {
7146                throw new IllegalArgumentException("File descriptors passed in options");
7147            }
7148        }
7149
7150        synchronized(this) {
7151            int callingUid = Binder.getCallingUid();
7152            int origUserId = userId;
7153            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7154                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7155                    ALLOW_NON_FULL, "getIntentSender", null);
7156            if (origUserId == UserHandle.USER_CURRENT) {
7157                // We don't want to evaluate this until the pending intent is
7158                // actually executed.  However, we do want to always do the
7159                // security checking for it above.
7160                userId = UserHandle.USER_CURRENT;
7161            }
7162            try {
7163                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7164                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7165                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7166                    if (!UserHandle.isSameApp(callingUid, uid)) {
7167                        String msg = "Permission Denial: getIntentSender() from pid="
7168                            + Binder.getCallingPid()
7169                            + ", uid=" + Binder.getCallingUid()
7170                            + ", (need uid=" + uid + ")"
7171                            + " is not allowed to send as package " + packageName;
7172                        Slog.w(TAG, msg);
7173                        throw new SecurityException(msg);
7174                    }
7175                }
7176
7177                return getIntentSenderLocked(type, packageName, callingUid, userId,
7178                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7179
7180            } catch (RemoteException e) {
7181                throw new SecurityException(e);
7182            }
7183        }
7184    }
7185
7186    IIntentSender getIntentSenderLocked(int type, String packageName,
7187            int callingUid, int userId, IBinder token, String resultWho,
7188            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7189            Bundle bOptions) {
7190        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7191        ActivityRecord activity = null;
7192        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7193            activity = ActivityRecord.isInStackLocked(token);
7194            if (activity == null) {
7195                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7196                return null;
7197            }
7198            if (activity.finishing) {
7199                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7200                return null;
7201            }
7202        }
7203
7204        // We're going to be splicing together extras before sending, so we're
7205        // okay poking into any contained extras.
7206        if (intents != null) {
7207            for (int i = 0; i < intents.length; i++) {
7208                intents[i].setDefusable(true);
7209            }
7210        }
7211        Bundle.setDefusable(bOptions, true);
7212
7213        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7214        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7215        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7216        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7217                |PendingIntent.FLAG_UPDATE_CURRENT);
7218
7219        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7220                type, packageName, activity, resultWho,
7221                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7222        WeakReference<PendingIntentRecord> ref;
7223        ref = mIntentSenderRecords.get(key);
7224        PendingIntentRecord rec = ref != null ? ref.get() : null;
7225        if (rec != null) {
7226            if (!cancelCurrent) {
7227                if (updateCurrent) {
7228                    if (rec.key.requestIntent != null) {
7229                        rec.key.requestIntent.replaceExtras(intents != null ?
7230                                intents[intents.length - 1] : null);
7231                    }
7232                    if (intents != null) {
7233                        intents[intents.length-1] = rec.key.requestIntent;
7234                        rec.key.allIntents = intents;
7235                        rec.key.allResolvedTypes = resolvedTypes;
7236                    } else {
7237                        rec.key.allIntents = null;
7238                        rec.key.allResolvedTypes = null;
7239                    }
7240                }
7241                return rec;
7242            }
7243            rec.canceled = true;
7244            mIntentSenderRecords.remove(key);
7245        }
7246        if (noCreate) {
7247            return rec;
7248        }
7249        rec = new PendingIntentRecord(this, key, callingUid);
7250        mIntentSenderRecords.put(key, rec.ref);
7251        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7252            if (activity.pendingResults == null) {
7253                activity.pendingResults
7254                        = new HashSet<WeakReference<PendingIntentRecord>>();
7255            }
7256            activity.pendingResults.add(rec.ref);
7257        }
7258        return rec;
7259    }
7260
7261    @Override
7262    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7263            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7264        if (target instanceof PendingIntentRecord) {
7265            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7266                    finishedReceiver, requiredPermission, options);
7267        } else {
7268            if (intent == null) {
7269                // Weird case: someone has given us their own custom IIntentSender, and now
7270                // they have someone else trying to send to it but of course this isn't
7271                // really a PendingIntent, so there is no base Intent, and the caller isn't
7272                // supplying an Intent... but we never want to dispatch a null Intent to
7273                // a receiver, so um...  let's make something up.
7274                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7275                intent = new Intent(Intent.ACTION_MAIN);
7276            }
7277            try {
7278                target.send(code, intent, resolvedType, null, requiredPermission, options);
7279            } catch (RemoteException e) {
7280            }
7281            // Platform code can rely on getting a result back when the send is done, but if
7282            // this intent sender is from outside of the system we can't rely on it doing that.
7283            // So instead we don't give it the result receiver, and instead just directly
7284            // report the finish immediately.
7285            if (finishedReceiver != null) {
7286                try {
7287                    finishedReceiver.performReceive(intent, 0,
7288                            null, null, false, false, UserHandle.getCallingUserId());
7289                } catch (RemoteException e) {
7290                }
7291            }
7292            return 0;
7293        }
7294    }
7295
7296    /**
7297     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7298     *
7299     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7300     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7301     */
7302    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7303        if (DEBUG_WHITELISTS) {
7304            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7305                    + targetUid + ", " + duration + ")");
7306        }
7307        synchronized (mPidsSelfLocked) {
7308            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7309            if (pr == null) {
7310                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7311                return;
7312            }
7313            if (!pr.whitelistManager) {
7314                if (DEBUG_WHITELISTS) {
7315                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7316                            + callerPid + " is not allowed");
7317                }
7318                return;
7319            }
7320        }
7321
7322        final long token = Binder.clearCallingIdentity();
7323        try {
7324            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7325                    true, "pe from uid:" + callerUid);
7326        } finally {
7327            Binder.restoreCallingIdentity(token);
7328        }
7329    }
7330
7331    @Override
7332    public void cancelIntentSender(IIntentSender sender) {
7333        if (!(sender instanceof PendingIntentRecord)) {
7334            return;
7335        }
7336        synchronized(this) {
7337            PendingIntentRecord rec = (PendingIntentRecord)sender;
7338            try {
7339                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7340                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7341                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7342                    String msg = "Permission Denial: cancelIntentSender() from pid="
7343                        + Binder.getCallingPid()
7344                        + ", uid=" + Binder.getCallingUid()
7345                        + " is not allowed to cancel packges "
7346                        + rec.key.packageName;
7347                    Slog.w(TAG, msg);
7348                    throw new SecurityException(msg);
7349                }
7350            } catch (RemoteException e) {
7351                throw new SecurityException(e);
7352            }
7353            cancelIntentSenderLocked(rec, true);
7354        }
7355    }
7356
7357    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7358        rec.canceled = true;
7359        mIntentSenderRecords.remove(rec.key);
7360        if (cleanActivity && rec.key.activity != null) {
7361            rec.key.activity.pendingResults.remove(rec.ref);
7362        }
7363    }
7364
7365    @Override
7366    public String getPackageForIntentSender(IIntentSender pendingResult) {
7367        if (!(pendingResult instanceof PendingIntentRecord)) {
7368            return null;
7369        }
7370        try {
7371            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7372            return res.key.packageName;
7373        } catch (ClassCastException e) {
7374        }
7375        return null;
7376    }
7377
7378    @Override
7379    public int getUidForIntentSender(IIntentSender sender) {
7380        if (sender instanceof PendingIntentRecord) {
7381            try {
7382                PendingIntentRecord res = (PendingIntentRecord)sender;
7383                return res.uid;
7384            } catch (ClassCastException e) {
7385            }
7386        }
7387        return -1;
7388    }
7389
7390    @Override
7391    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7392        if (!(pendingResult instanceof PendingIntentRecord)) {
7393            return false;
7394        }
7395        try {
7396            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7397            if (res.key.allIntents == null) {
7398                return false;
7399            }
7400            for (int i=0; i<res.key.allIntents.length; i++) {
7401                Intent intent = res.key.allIntents[i];
7402                if (intent.getPackage() != null && intent.getComponent() != null) {
7403                    return false;
7404                }
7405            }
7406            return true;
7407        } catch (ClassCastException e) {
7408        }
7409        return false;
7410    }
7411
7412    @Override
7413    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7414        if (!(pendingResult instanceof PendingIntentRecord)) {
7415            return false;
7416        }
7417        try {
7418            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7419            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7420                return true;
7421            }
7422            return false;
7423        } catch (ClassCastException e) {
7424        }
7425        return false;
7426    }
7427
7428    @Override
7429    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7430        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7431                "getIntentForIntentSender()");
7432        if (!(pendingResult instanceof PendingIntentRecord)) {
7433            return null;
7434        }
7435        try {
7436            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7437            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7438        } catch (ClassCastException e) {
7439        }
7440        return null;
7441    }
7442
7443    @Override
7444    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7445        if (!(pendingResult instanceof PendingIntentRecord)) {
7446            return null;
7447        }
7448        try {
7449            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7450            synchronized (this) {
7451                return getTagForIntentSenderLocked(res, prefix);
7452            }
7453        } catch (ClassCastException e) {
7454        }
7455        return null;
7456    }
7457
7458    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7459        final Intent intent = res.key.requestIntent;
7460        if (intent != null) {
7461            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7462                    || res.lastTagPrefix.equals(prefix))) {
7463                return res.lastTag;
7464            }
7465            res.lastTagPrefix = prefix;
7466            final StringBuilder sb = new StringBuilder(128);
7467            if (prefix != null) {
7468                sb.append(prefix);
7469            }
7470            if (intent.getAction() != null) {
7471                sb.append(intent.getAction());
7472            } else if (intent.getComponent() != null) {
7473                intent.getComponent().appendShortString(sb);
7474            } else {
7475                sb.append("?");
7476            }
7477            return res.lastTag = sb.toString();
7478        }
7479        return null;
7480    }
7481
7482    @Override
7483    public void setProcessLimit(int max) {
7484        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7485                "setProcessLimit()");
7486        synchronized (this) {
7487            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7488            mProcessLimitOverride = max;
7489        }
7490        trimApplications();
7491    }
7492
7493    @Override
7494    public int getProcessLimit() {
7495        synchronized (this) {
7496            return mProcessLimitOverride;
7497        }
7498    }
7499
7500    void foregroundTokenDied(ForegroundToken token) {
7501        synchronized (ActivityManagerService.this) {
7502            synchronized (mPidsSelfLocked) {
7503                ForegroundToken cur
7504                    = mForegroundProcesses.get(token.pid);
7505                if (cur != token) {
7506                    return;
7507                }
7508                mForegroundProcesses.remove(token.pid);
7509                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7510                if (pr == null) {
7511                    return;
7512                }
7513                pr.forcingToForeground = null;
7514                updateProcessForegroundLocked(pr, false, false);
7515            }
7516            updateOomAdjLocked();
7517        }
7518    }
7519
7520    @Override
7521    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7522        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7523                "setProcessForeground()");
7524        synchronized(this) {
7525            boolean changed = false;
7526
7527            synchronized (mPidsSelfLocked) {
7528                ProcessRecord pr = mPidsSelfLocked.get(pid);
7529                if (pr == null && isForeground) {
7530                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7531                    return;
7532                }
7533                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7534                if (oldToken != null) {
7535                    oldToken.token.unlinkToDeath(oldToken, 0);
7536                    mForegroundProcesses.remove(pid);
7537                    if (pr != null) {
7538                        pr.forcingToForeground = null;
7539                    }
7540                    changed = true;
7541                }
7542                if (isForeground && token != null) {
7543                    ForegroundToken newToken = new ForegroundToken() {
7544                        @Override
7545                        public void binderDied() {
7546                            foregroundTokenDied(this);
7547                        }
7548                    };
7549                    newToken.pid = pid;
7550                    newToken.token = token;
7551                    try {
7552                        token.linkToDeath(newToken, 0);
7553                        mForegroundProcesses.put(pid, newToken);
7554                        pr.forcingToForeground = token;
7555                        changed = true;
7556                    } catch (RemoteException e) {
7557                        // If the process died while doing this, we will later
7558                        // do the cleanup with the process death link.
7559                    }
7560                }
7561            }
7562
7563            if (changed) {
7564                updateOomAdjLocked();
7565            }
7566        }
7567    }
7568
7569    @Override
7570    public boolean isAppForeground(int uid) throws RemoteException {
7571        synchronized (this) {
7572            UidRecord uidRec = mActiveUids.get(uid);
7573            if (uidRec == null || uidRec.idle) {
7574                return false;
7575            }
7576            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7577        }
7578    }
7579
7580    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7581    // be guarded by permission checking.
7582    int getUidState(int uid) {
7583        synchronized (this) {
7584            UidRecord uidRec = mActiveUids.get(uid);
7585            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7586        }
7587    }
7588
7589    @Override
7590    public boolean isInMultiWindowMode(IBinder token) {
7591        final long origId = Binder.clearCallingIdentity();
7592        try {
7593            synchronized(this) {
7594                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7595                if (r == null) {
7596                    return false;
7597                }
7598                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7599                return !r.task.mFullscreen;
7600            }
7601        } finally {
7602            Binder.restoreCallingIdentity(origId);
7603        }
7604    }
7605
7606    @Override
7607    public boolean isInPictureInPictureMode(IBinder token) {
7608        final long origId = Binder.clearCallingIdentity();
7609        try {
7610            synchronized(this) {
7611                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7612                if (stack == null) {
7613                    return false;
7614                }
7615                return stack.mStackId == PINNED_STACK_ID;
7616            }
7617        } finally {
7618            Binder.restoreCallingIdentity(origId);
7619        }
7620    }
7621
7622    @Override
7623    public void enterPictureInPictureMode(IBinder token) {
7624        final long origId = Binder.clearCallingIdentity();
7625        try {
7626            synchronized(this) {
7627                if (!mSupportsPictureInPicture) {
7628                    throw new IllegalStateException("enterPictureInPictureMode: "
7629                            + "Device doesn't support picture-in-picture mode.");
7630                }
7631
7632                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7633
7634                if (r == null) {
7635                    throw new IllegalStateException("enterPictureInPictureMode: "
7636                            + "Can't find activity for token=" + token);
7637                }
7638
7639                if (!r.supportsPictureInPicture()) {
7640                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7641                            + "Picture-In-Picture not supported for r=" + r);
7642                }
7643
7644                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7645                // current bounds.
7646                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7647                final Rect bounds = (pinnedStack != null)
7648                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7649
7650                mStackSupervisor.moveActivityToPinnedStackLocked(
7651                        r, "enterPictureInPictureMode", bounds);
7652            }
7653        } finally {
7654            Binder.restoreCallingIdentity(origId);
7655        }
7656    }
7657
7658    // =========================================================
7659    // PROCESS INFO
7660    // =========================================================
7661
7662    static class ProcessInfoService extends IProcessInfoService.Stub {
7663        final ActivityManagerService mActivityManagerService;
7664        ProcessInfoService(ActivityManagerService activityManagerService) {
7665            mActivityManagerService = activityManagerService;
7666        }
7667
7668        @Override
7669        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7670            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7671                    /*in*/ pids, /*out*/ states, null);
7672        }
7673
7674        @Override
7675        public void getProcessStatesAndOomScoresFromPids(
7676                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7677            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7678                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7679        }
7680    }
7681
7682    /**
7683     * For each PID in the given input array, write the current process state
7684     * for that process into the states array, or -1 to indicate that no
7685     * process with the given PID exists. If scores array is provided, write
7686     * the oom score for the process into the scores array, with INVALID_ADJ
7687     * indicating the PID doesn't exist.
7688     */
7689    public void getProcessStatesAndOomScoresForPIDs(
7690            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7691        if (scores != null) {
7692            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7693                    "getProcessStatesAndOomScoresForPIDs()");
7694        }
7695
7696        if (pids == null) {
7697            throw new NullPointerException("pids");
7698        } else if (states == null) {
7699            throw new NullPointerException("states");
7700        } else if (pids.length != states.length) {
7701            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7702        } else if (scores != null && pids.length != scores.length) {
7703            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7704        }
7705
7706        synchronized (mPidsSelfLocked) {
7707            for (int i = 0; i < pids.length; i++) {
7708                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7709                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7710                        pr.curProcState;
7711                if (scores != null) {
7712                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7713                }
7714            }
7715        }
7716    }
7717
7718    // =========================================================
7719    // PERMISSIONS
7720    // =========================================================
7721
7722    static class PermissionController extends IPermissionController.Stub {
7723        ActivityManagerService mActivityManagerService;
7724        PermissionController(ActivityManagerService activityManagerService) {
7725            mActivityManagerService = activityManagerService;
7726        }
7727
7728        @Override
7729        public boolean checkPermission(String permission, int pid, int uid) {
7730            return mActivityManagerService.checkPermission(permission, pid,
7731                    uid) == PackageManager.PERMISSION_GRANTED;
7732        }
7733
7734        @Override
7735        public String[] getPackagesForUid(int uid) {
7736            return mActivityManagerService.mContext.getPackageManager()
7737                    .getPackagesForUid(uid);
7738        }
7739
7740        @Override
7741        public boolean isRuntimePermission(String permission) {
7742            try {
7743                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7744                        .getPermissionInfo(permission, 0);
7745                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7746            } catch (NameNotFoundException nnfe) {
7747                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7748            }
7749            return false;
7750        }
7751    }
7752
7753    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7754        @Override
7755        public int checkComponentPermission(String permission, int pid, int uid,
7756                int owningUid, boolean exported) {
7757            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7758                    owningUid, exported);
7759        }
7760
7761        @Override
7762        public Object getAMSLock() {
7763            return ActivityManagerService.this;
7764        }
7765    }
7766
7767    /**
7768     * This can be called with or without the global lock held.
7769     */
7770    int checkComponentPermission(String permission, int pid, int uid,
7771            int owningUid, boolean exported) {
7772        if (pid == MY_PID) {
7773            return PackageManager.PERMISSION_GRANTED;
7774        }
7775        return ActivityManager.checkComponentPermission(permission, uid,
7776                owningUid, exported);
7777    }
7778
7779    /**
7780     * As the only public entry point for permissions checking, this method
7781     * can enforce the semantic that requesting a check on a null global
7782     * permission is automatically denied.  (Internally a null permission
7783     * string is used when calling {@link #checkComponentPermission} in cases
7784     * when only uid-based security is needed.)
7785     *
7786     * This can be called with or without the global lock held.
7787     */
7788    @Override
7789    public int checkPermission(String permission, int pid, int uid) {
7790        if (permission == null) {
7791            return PackageManager.PERMISSION_DENIED;
7792        }
7793        return checkComponentPermission(permission, pid, uid, -1, true);
7794    }
7795
7796    @Override
7797    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7798        if (permission == null) {
7799            return PackageManager.PERMISSION_DENIED;
7800        }
7801
7802        // We might be performing an operation on behalf of an indirect binder
7803        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7804        // client identity accordingly before proceeding.
7805        Identity tlsIdentity = sCallerIdentity.get();
7806        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7807            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7808                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7809            uid = tlsIdentity.uid;
7810            pid = tlsIdentity.pid;
7811        }
7812
7813        return checkComponentPermission(permission, pid, uid, -1, true);
7814    }
7815
7816    /**
7817     * Binder IPC calls go through the public entry point.
7818     * This can be called with or without the global lock held.
7819     */
7820    int checkCallingPermission(String permission) {
7821        return checkPermission(permission,
7822                Binder.getCallingPid(),
7823                UserHandle.getAppId(Binder.getCallingUid()));
7824    }
7825
7826    /**
7827     * This can be called with or without the global lock held.
7828     */
7829    void enforceCallingPermission(String permission, String func) {
7830        if (checkCallingPermission(permission)
7831                == PackageManager.PERMISSION_GRANTED) {
7832            return;
7833        }
7834
7835        String msg = "Permission Denial: " + func + " from pid="
7836                + Binder.getCallingPid()
7837                + ", uid=" + Binder.getCallingUid()
7838                + " requires " + permission;
7839        Slog.w(TAG, msg);
7840        throw new SecurityException(msg);
7841    }
7842
7843    /**
7844     * Determine if UID is holding permissions required to access {@link Uri} in
7845     * the given {@link ProviderInfo}. Final permission checking is always done
7846     * in {@link ContentProvider}.
7847     */
7848    private final boolean checkHoldingPermissionsLocked(
7849            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7850        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7851                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7852        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7853            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7854                    != PERMISSION_GRANTED) {
7855                return false;
7856            }
7857        }
7858        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7859    }
7860
7861    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7862            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7863        if (pi.applicationInfo.uid == uid) {
7864            return true;
7865        } else if (!pi.exported) {
7866            return false;
7867        }
7868
7869        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7870        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7871        try {
7872            // check if target holds top-level <provider> permissions
7873            if (!readMet && pi.readPermission != null && considerUidPermissions
7874                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7875                readMet = true;
7876            }
7877            if (!writeMet && pi.writePermission != null && considerUidPermissions
7878                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7879                writeMet = true;
7880            }
7881
7882            // track if unprotected read/write is allowed; any denied
7883            // <path-permission> below removes this ability
7884            boolean allowDefaultRead = pi.readPermission == null;
7885            boolean allowDefaultWrite = pi.writePermission == null;
7886
7887            // check if target holds any <path-permission> that match uri
7888            final PathPermission[] pps = pi.pathPermissions;
7889            if (pps != null) {
7890                final String path = grantUri.uri.getPath();
7891                int i = pps.length;
7892                while (i > 0 && (!readMet || !writeMet)) {
7893                    i--;
7894                    PathPermission pp = pps[i];
7895                    if (pp.match(path)) {
7896                        if (!readMet) {
7897                            final String pprperm = pp.getReadPermission();
7898                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7899                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7900                                    + ": match=" + pp.match(path)
7901                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7902                            if (pprperm != null) {
7903                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7904                                        == PERMISSION_GRANTED) {
7905                                    readMet = true;
7906                                } else {
7907                                    allowDefaultRead = false;
7908                                }
7909                            }
7910                        }
7911                        if (!writeMet) {
7912                            final String ppwperm = pp.getWritePermission();
7913                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7914                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7915                                    + ": match=" + pp.match(path)
7916                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7917                            if (ppwperm != null) {
7918                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7919                                        == PERMISSION_GRANTED) {
7920                                    writeMet = true;
7921                                } else {
7922                                    allowDefaultWrite = false;
7923                                }
7924                            }
7925                        }
7926                    }
7927                }
7928            }
7929
7930            // grant unprotected <provider> read/write, if not blocked by
7931            // <path-permission> above
7932            if (allowDefaultRead) readMet = true;
7933            if (allowDefaultWrite) writeMet = true;
7934
7935        } catch (RemoteException e) {
7936            return false;
7937        }
7938
7939        return readMet && writeMet;
7940    }
7941
7942    public int getAppStartMode(int uid, String packageName) {
7943        synchronized (this) {
7944            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7945        }
7946    }
7947
7948    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7949            boolean allowWhenForeground) {
7950        UidRecord uidRec = mActiveUids.get(uid);
7951        if (!mLenientBackgroundCheck) {
7952            if (!allowWhenForeground || uidRec == null
7953                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7954                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7955                        packageName) != AppOpsManager.MODE_ALLOWED) {
7956                    return ActivityManager.APP_START_MODE_DELAYED;
7957                }
7958            }
7959
7960        } else if (uidRec == null || uidRec.idle) {
7961            if (callingPid >= 0) {
7962                ProcessRecord proc;
7963                synchronized (mPidsSelfLocked) {
7964                    proc = mPidsSelfLocked.get(callingPid);
7965                }
7966                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7967                    // Whoever is instigating this is in the foreground, so we will allow it
7968                    // to go through.
7969                    return ActivityManager.APP_START_MODE_NORMAL;
7970                }
7971            }
7972            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7973                    != AppOpsManager.MODE_ALLOWED) {
7974                return ActivityManager.APP_START_MODE_DELAYED;
7975            }
7976        }
7977        return ActivityManager.APP_START_MODE_NORMAL;
7978    }
7979
7980    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7981        ProviderInfo pi = null;
7982        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7983        if (cpr != null) {
7984            pi = cpr.info;
7985        } else {
7986            try {
7987                pi = AppGlobals.getPackageManager().resolveContentProvider(
7988                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7989                        userHandle);
7990            } catch (RemoteException ex) {
7991            }
7992        }
7993        return pi;
7994    }
7995
7996    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7997        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7998        if (targetUris != null) {
7999            return targetUris.get(grantUri);
8000        }
8001        return null;
8002    }
8003
8004    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8005            String targetPkg, int targetUid, GrantUri grantUri) {
8006        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8007        if (targetUris == null) {
8008            targetUris = Maps.newArrayMap();
8009            mGrantedUriPermissions.put(targetUid, targetUris);
8010        }
8011
8012        UriPermission perm = targetUris.get(grantUri);
8013        if (perm == null) {
8014            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8015            targetUris.put(grantUri, perm);
8016        }
8017
8018        return perm;
8019    }
8020
8021    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8022            final int modeFlags) {
8023        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8024        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8025                : UriPermission.STRENGTH_OWNED;
8026
8027        // Root gets to do everything.
8028        if (uid == 0) {
8029            return true;
8030        }
8031
8032        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8033        if (perms == null) return false;
8034
8035        // First look for exact match
8036        final UriPermission exactPerm = perms.get(grantUri);
8037        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8038            return true;
8039        }
8040
8041        // No exact match, look for prefixes
8042        final int N = perms.size();
8043        for (int i = 0; i < N; i++) {
8044            final UriPermission perm = perms.valueAt(i);
8045            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8046                    && perm.getStrength(modeFlags) >= minStrength) {
8047                return true;
8048            }
8049        }
8050
8051        return false;
8052    }
8053
8054    /**
8055     * @param uri This uri must NOT contain an embedded userId.
8056     * @param userId The userId in which the uri is to be resolved.
8057     */
8058    @Override
8059    public int checkUriPermission(Uri uri, int pid, int uid,
8060            final int modeFlags, int userId, IBinder callerToken) {
8061        enforceNotIsolatedCaller("checkUriPermission");
8062
8063        // Another redirected-binder-call permissions check as in
8064        // {@link checkPermissionWithToken}.
8065        Identity tlsIdentity = sCallerIdentity.get();
8066        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8067            uid = tlsIdentity.uid;
8068            pid = tlsIdentity.pid;
8069        }
8070
8071        // Our own process gets to do everything.
8072        if (pid == MY_PID) {
8073            return PackageManager.PERMISSION_GRANTED;
8074        }
8075        synchronized (this) {
8076            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8077                    ? PackageManager.PERMISSION_GRANTED
8078                    : PackageManager.PERMISSION_DENIED;
8079        }
8080    }
8081
8082    /**
8083     * Check if the targetPkg can be granted permission to access uri by
8084     * the callingUid using the given modeFlags.  Throws a security exception
8085     * if callingUid is not allowed to do this.  Returns the uid of the target
8086     * if the URI permission grant should be performed; returns -1 if it is not
8087     * needed (for example targetPkg already has permission to access the URI).
8088     * If you already know the uid of the target, you can supply it in
8089     * lastTargetUid else set that to -1.
8090     */
8091    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8092            final int modeFlags, int lastTargetUid) {
8093        if (!Intent.isAccessUriMode(modeFlags)) {
8094            return -1;
8095        }
8096
8097        if (targetPkg != null) {
8098            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                    "Checking grant " + targetPkg + " permission to " + grantUri);
8100        }
8101
8102        final IPackageManager pm = AppGlobals.getPackageManager();
8103
8104        // If this is not a content: uri, we can't do anything with it.
8105        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8106            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8107                    "Can't grant URI permission for non-content URI: " + grantUri);
8108            return -1;
8109        }
8110
8111        final String authority = grantUri.uri.getAuthority();
8112        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8113                MATCH_DEBUG_TRIAGED_MISSING);
8114        if (pi == null) {
8115            Slog.w(TAG, "No content provider found for permission check: " +
8116                    grantUri.uri.toSafeString());
8117            return -1;
8118        }
8119
8120        int targetUid = lastTargetUid;
8121        if (targetUid < 0 && targetPkg != null) {
8122            try {
8123                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8124                        UserHandle.getUserId(callingUid));
8125                if (targetUid < 0) {
8126                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8127                            "Can't grant URI permission no uid for: " + targetPkg);
8128                    return -1;
8129                }
8130            } catch (RemoteException ex) {
8131                return -1;
8132            }
8133        }
8134
8135        if (targetUid >= 0) {
8136            // First...  does the target actually need this permission?
8137            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8138                // No need to grant the target this permission.
8139                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8140                        "Target " + targetPkg + " already has full permission to " + grantUri);
8141                return -1;
8142            }
8143        } else {
8144            // First...  there is no target package, so can anyone access it?
8145            boolean allowed = pi.exported;
8146            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8147                if (pi.readPermission != null) {
8148                    allowed = false;
8149                }
8150            }
8151            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8152                if (pi.writePermission != null) {
8153                    allowed = false;
8154                }
8155            }
8156            if (allowed) {
8157                return -1;
8158            }
8159        }
8160
8161        /* There is a special cross user grant if:
8162         * - The target is on another user.
8163         * - Apps on the current user can access the uri without any uid permissions.
8164         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8165         * grant uri permissions.
8166         */
8167        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8168                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8169                modeFlags, false /*without considering the uid permissions*/);
8170
8171        // Second...  is the provider allowing granting of URI permissions?
8172        if (!specialCrossUserGrant) {
8173            if (!pi.grantUriPermissions) {
8174                throw new SecurityException("Provider " + pi.packageName
8175                        + "/" + pi.name
8176                        + " does not allow granting of Uri permissions (uri "
8177                        + grantUri + ")");
8178            }
8179            if (pi.uriPermissionPatterns != null) {
8180                final int N = pi.uriPermissionPatterns.length;
8181                boolean allowed = false;
8182                for (int i=0; i<N; i++) {
8183                    if (pi.uriPermissionPatterns[i] != null
8184                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8185                        allowed = true;
8186                        break;
8187                    }
8188                }
8189                if (!allowed) {
8190                    throw new SecurityException("Provider " + pi.packageName
8191                            + "/" + pi.name
8192                            + " does not allow granting of permission to path of Uri "
8193                            + grantUri);
8194                }
8195            }
8196        }
8197
8198        // Third...  does the caller itself have permission to access
8199        // this uri?
8200        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8201            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8202                // Require they hold a strong enough Uri permission
8203                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8204                    throw new SecurityException("Uid " + callingUid
8205                            + " does not have permission to uri " + grantUri);
8206                }
8207            }
8208        }
8209        return targetUid;
8210    }
8211
8212    /**
8213     * @param uri This uri must NOT contain an embedded userId.
8214     * @param userId The userId in which the uri is to be resolved.
8215     */
8216    @Override
8217    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8218            final int modeFlags, int userId) {
8219        enforceNotIsolatedCaller("checkGrantUriPermission");
8220        synchronized(this) {
8221            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8222                    new GrantUri(userId, uri, false), modeFlags, -1);
8223        }
8224    }
8225
8226    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8227            final int modeFlags, UriPermissionOwner owner) {
8228        if (!Intent.isAccessUriMode(modeFlags)) {
8229            return;
8230        }
8231
8232        // So here we are: the caller has the assumed permission
8233        // to the uri, and the target doesn't.  Let's now give this to
8234        // the target.
8235
8236        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8237                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8238
8239        final String authority = grantUri.uri.getAuthority();
8240        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8241                MATCH_DEBUG_TRIAGED_MISSING);
8242        if (pi == null) {
8243            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8244            return;
8245        }
8246
8247        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8248            grantUri.prefix = true;
8249        }
8250        final UriPermission perm = findOrCreateUriPermissionLocked(
8251                pi.packageName, targetPkg, targetUid, grantUri);
8252        perm.grantModes(modeFlags, owner);
8253    }
8254
8255    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8256            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8257        if (targetPkg == null) {
8258            throw new NullPointerException("targetPkg");
8259        }
8260        int targetUid;
8261        final IPackageManager pm = AppGlobals.getPackageManager();
8262        try {
8263            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8264        } catch (RemoteException ex) {
8265            return;
8266        }
8267
8268        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8269                targetUid);
8270        if (targetUid < 0) {
8271            return;
8272        }
8273
8274        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8275                owner);
8276    }
8277
8278    static class NeededUriGrants extends ArrayList<GrantUri> {
8279        final String targetPkg;
8280        final int targetUid;
8281        final int flags;
8282
8283        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8284            this.targetPkg = targetPkg;
8285            this.targetUid = targetUid;
8286            this.flags = flags;
8287        }
8288    }
8289
8290    /**
8291     * Like checkGrantUriPermissionLocked, but takes an Intent.
8292     */
8293    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8294            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8295        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8296                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8297                + " clip=" + (intent != null ? intent.getClipData() : null)
8298                + " from " + intent + "; flags=0x"
8299                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8300
8301        if (targetPkg == null) {
8302            throw new NullPointerException("targetPkg");
8303        }
8304
8305        if (intent == null) {
8306            return null;
8307        }
8308        Uri data = intent.getData();
8309        ClipData clip = intent.getClipData();
8310        if (data == null && clip == null) {
8311            return null;
8312        }
8313        // Default userId for uris in the intent (if they don't specify it themselves)
8314        int contentUserHint = intent.getContentUserHint();
8315        if (contentUserHint == UserHandle.USER_CURRENT) {
8316            contentUserHint = UserHandle.getUserId(callingUid);
8317        }
8318        final IPackageManager pm = AppGlobals.getPackageManager();
8319        int targetUid;
8320        if (needed != null) {
8321            targetUid = needed.targetUid;
8322        } else {
8323            try {
8324                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8325                        targetUserId);
8326            } catch (RemoteException ex) {
8327                return null;
8328            }
8329            if (targetUid < 0) {
8330                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8331                        "Can't grant URI permission no uid for: " + targetPkg
8332                        + " on user " + targetUserId);
8333                return null;
8334            }
8335        }
8336        if (data != null) {
8337            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8338            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8339                    targetUid);
8340            if (targetUid > 0) {
8341                if (needed == null) {
8342                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8343                }
8344                needed.add(grantUri);
8345            }
8346        }
8347        if (clip != null) {
8348            for (int i=0; i<clip.getItemCount(); i++) {
8349                Uri uri = clip.getItemAt(i).getUri();
8350                if (uri != null) {
8351                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8352                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8353                            targetUid);
8354                    if (targetUid > 0) {
8355                        if (needed == null) {
8356                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8357                        }
8358                        needed.add(grantUri);
8359                    }
8360                } else {
8361                    Intent clipIntent = clip.getItemAt(i).getIntent();
8362                    if (clipIntent != null) {
8363                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8364                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8365                        if (newNeeded != null) {
8366                            needed = newNeeded;
8367                        }
8368                    }
8369                }
8370            }
8371        }
8372
8373        return needed;
8374    }
8375
8376    /**
8377     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8378     */
8379    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8380            UriPermissionOwner owner) {
8381        if (needed != null) {
8382            for (int i=0; i<needed.size(); i++) {
8383                GrantUri grantUri = needed.get(i);
8384                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8385                        grantUri, needed.flags, owner);
8386            }
8387        }
8388    }
8389
8390    void grantUriPermissionFromIntentLocked(int callingUid,
8391            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8392        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8393                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8394        if (needed == null) {
8395            return;
8396        }
8397
8398        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8399    }
8400
8401    /**
8402     * @param uri This uri must NOT contain an embedded userId.
8403     * @param userId The userId in which the uri is to be resolved.
8404     */
8405    @Override
8406    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8407            final int modeFlags, int userId) {
8408        enforceNotIsolatedCaller("grantUriPermission");
8409        GrantUri grantUri = new GrantUri(userId, uri, false);
8410        synchronized(this) {
8411            final ProcessRecord r = getRecordForAppLocked(caller);
8412            if (r == null) {
8413                throw new SecurityException("Unable to find app for caller "
8414                        + caller
8415                        + " when granting permission to uri " + grantUri);
8416            }
8417            if (targetPkg == null) {
8418                throw new IllegalArgumentException("null target");
8419            }
8420            if (grantUri == null) {
8421                throw new IllegalArgumentException("null uri");
8422            }
8423
8424            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8425                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8426                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8427                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8428
8429            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8430                    UserHandle.getUserId(r.uid));
8431        }
8432    }
8433
8434    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8435        if (perm.modeFlags == 0) {
8436            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8437                    perm.targetUid);
8438            if (perms != null) {
8439                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8440                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8441
8442                perms.remove(perm.uri);
8443                if (perms.isEmpty()) {
8444                    mGrantedUriPermissions.remove(perm.targetUid);
8445                }
8446            }
8447        }
8448    }
8449
8450    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8451        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8452                "Revoking all granted permissions to " + grantUri);
8453
8454        final IPackageManager pm = AppGlobals.getPackageManager();
8455        final String authority = grantUri.uri.getAuthority();
8456        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8457                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8458        if (pi == null) {
8459            Slog.w(TAG, "No content provider found for permission revoke: "
8460                    + grantUri.toSafeString());
8461            return;
8462        }
8463
8464        // Does the caller have this permission on the URI?
8465        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8466            // If they don't have direct access to the URI, then revoke any
8467            // ownerless URI permissions that have been granted to them.
8468            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8469            if (perms != null) {
8470                boolean persistChanged = false;
8471                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8472                    final UriPermission perm = it.next();
8473                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8474                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8475                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8476                                "Revoking non-owned " + perm.targetUid
8477                                + " permission to " + perm.uri);
8478                        persistChanged |= perm.revokeModes(
8479                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8480                        if (perm.modeFlags == 0) {
8481                            it.remove();
8482                        }
8483                    }
8484                }
8485                if (perms.isEmpty()) {
8486                    mGrantedUriPermissions.remove(callingUid);
8487                }
8488                if (persistChanged) {
8489                    schedulePersistUriGrants();
8490                }
8491            }
8492            return;
8493        }
8494
8495        boolean persistChanged = false;
8496
8497        // Go through all of the permissions and remove any that match.
8498        int N = mGrantedUriPermissions.size();
8499        for (int i = 0; i < N; i++) {
8500            final int targetUid = mGrantedUriPermissions.keyAt(i);
8501            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8502
8503            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8504                final UriPermission perm = it.next();
8505                if (perm.uri.sourceUserId == grantUri.sourceUserId
8506                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8507                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8508                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8509                    persistChanged |= perm.revokeModes(
8510                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8511                    if (perm.modeFlags == 0) {
8512                        it.remove();
8513                    }
8514                }
8515            }
8516
8517            if (perms.isEmpty()) {
8518                mGrantedUriPermissions.remove(targetUid);
8519                N--;
8520                i--;
8521            }
8522        }
8523
8524        if (persistChanged) {
8525            schedulePersistUriGrants();
8526        }
8527    }
8528
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param userId The userId in which the uri is to be resolved.
8532     */
8533    @Override
8534    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8535            int userId) {
8536        enforceNotIsolatedCaller("revokeUriPermission");
8537        synchronized(this) {
8538            final ProcessRecord r = getRecordForAppLocked(caller);
8539            if (r == null) {
8540                throw new SecurityException("Unable to find app for caller "
8541                        + caller
8542                        + " when revoking permission to uri " + uri);
8543            }
8544            if (uri == null) {
8545                Slog.w(TAG, "revokeUriPermission: null uri");
8546                return;
8547            }
8548
8549            if (!Intent.isAccessUriMode(modeFlags)) {
8550                return;
8551            }
8552
8553            final String authority = uri.getAuthority();
8554            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8555                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8556            if (pi == null) {
8557                Slog.w(TAG, "No content provider found for permission revoke: "
8558                        + uri.toSafeString());
8559                return;
8560            }
8561
8562            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8563        }
8564    }
8565
8566    /**
8567     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8568     * given package.
8569     *
8570     * @param packageName Package name to match, or {@code null} to apply to all
8571     *            packages.
8572     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8573     *            to all users.
8574     * @param persistable If persistable grants should be removed.
8575     */
8576    private void removeUriPermissionsForPackageLocked(
8577            String packageName, int userHandle, boolean persistable) {
8578        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8579            throw new IllegalArgumentException("Must narrow by either package or user");
8580        }
8581
8582        boolean persistChanged = false;
8583
8584        int N = mGrantedUriPermissions.size();
8585        for (int i = 0; i < N; i++) {
8586            final int targetUid = mGrantedUriPermissions.keyAt(i);
8587            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8588
8589            // Only inspect grants matching user
8590            if (userHandle == UserHandle.USER_ALL
8591                    || userHandle == UserHandle.getUserId(targetUid)) {
8592                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8593                    final UriPermission perm = it.next();
8594
8595                    // Only inspect grants matching package
8596                    if (packageName == null || perm.sourcePkg.equals(packageName)
8597                            || perm.targetPkg.equals(packageName)) {
8598                        // Hacky solution as part of fixing a security bug; ignore
8599                        // grants associated with DownloadManager so we don't have
8600                        // to immediately launch it to regrant the permissions
8601                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8602                                && !persistable) continue;
8603
8604                        persistChanged |= perm.revokeModes(persistable
8605                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8606
8607                        // Only remove when no modes remain; any persisted grants
8608                        // will keep this alive.
8609                        if (perm.modeFlags == 0) {
8610                            it.remove();
8611                        }
8612                    }
8613                }
8614
8615                if (perms.isEmpty()) {
8616                    mGrantedUriPermissions.remove(targetUid);
8617                    N--;
8618                    i--;
8619                }
8620            }
8621        }
8622
8623        if (persistChanged) {
8624            schedulePersistUriGrants();
8625        }
8626    }
8627
8628    @Override
8629    public IBinder newUriPermissionOwner(String name) {
8630        enforceNotIsolatedCaller("newUriPermissionOwner");
8631        synchronized(this) {
8632            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8633            return owner.getExternalTokenLocked();
8634        }
8635    }
8636
8637    @Override
8638    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8639        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8640        synchronized(this) {
8641            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8642            if (r == null) {
8643                throw new IllegalArgumentException("Activity does not exist; token="
8644                        + activityToken);
8645            }
8646            return r.getUriPermissionsLocked().getExternalTokenLocked();
8647        }
8648    }
8649    /**
8650     * @param uri This uri must NOT contain an embedded userId.
8651     * @param sourceUserId The userId in which the uri is to be resolved.
8652     * @param targetUserId The userId of the app that receives the grant.
8653     */
8654    @Override
8655    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8656            final int modeFlags, int sourceUserId, int targetUserId) {
8657        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8658                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8659                "grantUriPermissionFromOwner", null);
8660        synchronized(this) {
8661            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8662            if (owner == null) {
8663                throw new IllegalArgumentException("Unknown owner: " + token);
8664            }
8665            if (fromUid != Binder.getCallingUid()) {
8666                if (Binder.getCallingUid() != Process.myUid()) {
8667                    // Only system code can grant URI permissions on behalf
8668                    // of other users.
8669                    throw new SecurityException("nice try");
8670                }
8671            }
8672            if (targetPkg == null) {
8673                throw new IllegalArgumentException("null target");
8674            }
8675            if (uri == null) {
8676                throw new IllegalArgumentException("null uri");
8677            }
8678
8679            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8680                    modeFlags, owner, targetUserId);
8681        }
8682    }
8683
8684    /**
8685     * @param uri This uri must NOT contain an embedded userId.
8686     * @param userId The userId in which the uri is to be resolved.
8687     */
8688    @Override
8689    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8690        synchronized(this) {
8691            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8692            if (owner == null) {
8693                throw new IllegalArgumentException("Unknown owner: " + token);
8694            }
8695
8696            if (uri == null) {
8697                owner.removeUriPermissionsLocked(mode);
8698            } else {
8699                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8700                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8701            }
8702        }
8703    }
8704
8705    private void schedulePersistUriGrants() {
8706        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8707            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8708                    10 * DateUtils.SECOND_IN_MILLIS);
8709        }
8710    }
8711
8712    private void writeGrantedUriPermissions() {
8713        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8714
8715        // Snapshot permissions so we can persist without lock
8716        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8717        synchronized (this) {
8718            final int size = mGrantedUriPermissions.size();
8719            for (int i = 0; i < size; i++) {
8720                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8721                for (UriPermission perm : perms.values()) {
8722                    if (perm.persistedModeFlags != 0) {
8723                        persist.add(perm.snapshot());
8724                    }
8725                }
8726            }
8727        }
8728
8729        FileOutputStream fos = null;
8730        try {
8731            fos = mGrantFile.startWrite();
8732
8733            XmlSerializer out = new FastXmlSerializer();
8734            out.setOutput(fos, StandardCharsets.UTF_8.name());
8735            out.startDocument(null, true);
8736            out.startTag(null, TAG_URI_GRANTS);
8737            for (UriPermission.Snapshot perm : persist) {
8738                out.startTag(null, TAG_URI_GRANT);
8739                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8740                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8741                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8742                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8743                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8744                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8745                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8746                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8747                out.endTag(null, TAG_URI_GRANT);
8748            }
8749            out.endTag(null, TAG_URI_GRANTS);
8750            out.endDocument();
8751
8752            mGrantFile.finishWrite(fos);
8753        } catch (IOException e) {
8754            if (fos != null) {
8755                mGrantFile.failWrite(fos);
8756            }
8757        }
8758    }
8759
8760    private void readGrantedUriPermissionsLocked() {
8761        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8762
8763        final long now = System.currentTimeMillis();
8764
8765        FileInputStream fis = null;
8766        try {
8767            fis = mGrantFile.openRead();
8768            final XmlPullParser in = Xml.newPullParser();
8769            in.setInput(fis, StandardCharsets.UTF_8.name());
8770
8771            int type;
8772            while ((type = in.next()) != END_DOCUMENT) {
8773                final String tag = in.getName();
8774                if (type == START_TAG) {
8775                    if (TAG_URI_GRANT.equals(tag)) {
8776                        final int sourceUserId;
8777                        final int targetUserId;
8778                        final int userHandle = readIntAttribute(in,
8779                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8780                        if (userHandle != UserHandle.USER_NULL) {
8781                            // For backwards compatibility.
8782                            sourceUserId = userHandle;
8783                            targetUserId = userHandle;
8784                        } else {
8785                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8786                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8787                        }
8788                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8789                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8790                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8791                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8792                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8793                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8794
8795                        // Sanity check that provider still belongs to source package
8796                        // Both direct boot aware and unaware packages are fine as we
8797                        // will do filtering at query time to avoid multiple parsing.
8798                        final ProviderInfo pi = getProviderInfoLocked(
8799                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8800                                        | MATCH_DIRECT_BOOT_UNAWARE);
8801                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8802                            int targetUid = -1;
8803                            try {
8804                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8805                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8806                            } catch (RemoteException e) {
8807                            }
8808                            if (targetUid != -1) {
8809                                final UriPermission perm = findOrCreateUriPermissionLocked(
8810                                        sourcePkg, targetPkg, targetUid,
8811                                        new GrantUri(sourceUserId, uri, prefix));
8812                                perm.initPersistedModes(modeFlags, createdTime);
8813                            }
8814                        } else {
8815                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8816                                    + " but instead found " + pi);
8817                        }
8818                    }
8819                }
8820            }
8821        } catch (FileNotFoundException e) {
8822            // Missing grants is okay
8823        } catch (IOException e) {
8824            Slog.wtf(TAG, "Failed reading Uri grants", e);
8825        } catch (XmlPullParserException e) {
8826            Slog.wtf(TAG, "Failed reading Uri grants", e);
8827        } finally {
8828            IoUtils.closeQuietly(fis);
8829        }
8830    }
8831
8832    /**
8833     * @param uri This uri must NOT contain an embedded userId.
8834     * @param userId The userId in which the uri is to be resolved.
8835     */
8836    @Override
8837    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8838        enforceNotIsolatedCaller("takePersistableUriPermission");
8839
8840        Preconditions.checkFlagsArgument(modeFlags,
8841                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8842
8843        synchronized (this) {
8844            final int callingUid = Binder.getCallingUid();
8845            boolean persistChanged = false;
8846            GrantUri grantUri = new GrantUri(userId, uri, false);
8847
8848            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8849                    new GrantUri(userId, uri, false));
8850            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8851                    new GrantUri(userId, uri, true));
8852
8853            final boolean exactValid = (exactPerm != null)
8854                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8855            final boolean prefixValid = (prefixPerm != null)
8856                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8857
8858            if (!(exactValid || prefixValid)) {
8859                throw new SecurityException("No persistable permission grants found for UID "
8860                        + callingUid + " and Uri " + grantUri.toSafeString());
8861            }
8862
8863            if (exactValid) {
8864                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8865            }
8866            if (prefixValid) {
8867                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8868            }
8869
8870            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8871
8872            if (persistChanged) {
8873                schedulePersistUriGrants();
8874            }
8875        }
8876    }
8877
8878    /**
8879     * @param uri This uri must NOT contain an embedded userId.
8880     * @param userId The userId in which the uri is to be resolved.
8881     */
8882    @Override
8883    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8884        enforceNotIsolatedCaller("releasePersistableUriPermission");
8885
8886        Preconditions.checkFlagsArgument(modeFlags,
8887                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8888
8889        synchronized (this) {
8890            final int callingUid = Binder.getCallingUid();
8891            boolean persistChanged = false;
8892
8893            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8894                    new GrantUri(userId, uri, false));
8895            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8896                    new GrantUri(userId, uri, true));
8897            if (exactPerm == null && prefixPerm == null) {
8898                throw new SecurityException("No permission grants found for UID " + callingUid
8899                        + " and Uri " + uri.toSafeString());
8900            }
8901
8902            if (exactPerm != null) {
8903                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8904                removeUriPermissionIfNeededLocked(exactPerm);
8905            }
8906            if (prefixPerm != null) {
8907                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8908                removeUriPermissionIfNeededLocked(prefixPerm);
8909            }
8910
8911            if (persistChanged) {
8912                schedulePersistUriGrants();
8913            }
8914        }
8915    }
8916
8917    /**
8918     * Prune any older {@link UriPermission} for the given UID until outstanding
8919     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8920     *
8921     * @return if any mutations occured that require persisting.
8922     */
8923    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8924        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8925        if (perms == null) return false;
8926        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8927
8928        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8929        for (UriPermission perm : perms.values()) {
8930            if (perm.persistedModeFlags != 0) {
8931                persisted.add(perm);
8932            }
8933        }
8934
8935        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8936        if (trimCount <= 0) return false;
8937
8938        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8939        for (int i = 0; i < trimCount; i++) {
8940            final UriPermission perm = persisted.get(i);
8941
8942            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8943                    "Trimming grant created at " + perm.persistedCreateTime);
8944
8945            perm.releasePersistableModes(~0);
8946            removeUriPermissionIfNeededLocked(perm);
8947        }
8948
8949        return true;
8950    }
8951
8952    @Override
8953    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8954            String packageName, boolean incoming) {
8955        enforceNotIsolatedCaller("getPersistedUriPermissions");
8956        Preconditions.checkNotNull(packageName, "packageName");
8957
8958        final int callingUid = Binder.getCallingUid();
8959        final int callingUserId = UserHandle.getUserId(callingUid);
8960        final IPackageManager pm = AppGlobals.getPackageManager();
8961        try {
8962            final int packageUid = pm.getPackageUid(packageName,
8963                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8964            if (packageUid != callingUid) {
8965                throw new SecurityException(
8966                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8967            }
8968        } catch (RemoteException e) {
8969            throw new SecurityException("Failed to verify package name ownership");
8970        }
8971
8972        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8973        synchronized (this) {
8974            if (incoming) {
8975                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8976                        callingUid);
8977                if (perms == null) {
8978                    Slog.w(TAG, "No permission grants found for " + packageName);
8979                } else {
8980                    for (UriPermission perm : perms.values()) {
8981                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8982                            result.add(perm.buildPersistedPublicApiObject());
8983                        }
8984                    }
8985                }
8986            } else {
8987                final int size = mGrantedUriPermissions.size();
8988                for (int i = 0; i < size; i++) {
8989                    final ArrayMap<GrantUri, UriPermission> perms =
8990                            mGrantedUriPermissions.valueAt(i);
8991                    for (UriPermission perm : perms.values()) {
8992                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8993                            result.add(perm.buildPersistedPublicApiObject());
8994                        }
8995                    }
8996                }
8997            }
8998        }
8999        return new ParceledListSlice<android.content.UriPermission>(result);
9000    }
9001
9002    @Override
9003    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9004            String packageName, int userId) {
9005        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9006                "getGrantedUriPermissions");
9007
9008        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9009        synchronized (this) {
9010            final int size = mGrantedUriPermissions.size();
9011            for (int i = 0; i < size; i++) {
9012                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9013                for (UriPermission perm : perms.values()) {
9014                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9015                            && perm.persistedModeFlags != 0) {
9016                        result.add(perm.buildPersistedPublicApiObject());
9017                    }
9018                }
9019            }
9020        }
9021        return new ParceledListSlice<android.content.UriPermission>(result);
9022    }
9023
9024    @Override
9025    public void clearGrantedUriPermissions(String packageName, int userId) {
9026        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9027                "clearGrantedUriPermissions");
9028        removeUriPermissionsForPackageLocked(packageName, userId, true);
9029    }
9030
9031    @Override
9032    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9033        synchronized (this) {
9034            ProcessRecord app =
9035                who != null ? getRecordForAppLocked(who) : null;
9036            if (app == null) return;
9037
9038            Message msg = Message.obtain();
9039            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9040            msg.obj = app;
9041            msg.arg1 = waiting ? 1 : 0;
9042            mUiHandler.sendMessage(msg);
9043        }
9044    }
9045
9046    @Override
9047    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9048        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9049        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9050        outInfo.availMem = Process.getFreeMemory();
9051        outInfo.totalMem = Process.getTotalMemory();
9052        outInfo.threshold = homeAppMem;
9053        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9054        outInfo.hiddenAppThreshold = cachedAppMem;
9055        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9056                ProcessList.SERVICE_ADJ);
9057        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9058                ProcessList.VISIBLE_APP_ADJ);
9059        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9060                ProcessList.FOREGROUND_APP_ADJ);
9061    }
9062
9063    // =========================================================
9064    // TASK MANAGEMENT
9065    // =========================================================
9066
9067    @Override
9068    public List<IAppTask> getAppTasks(String callingPackage) {
9069        int callingUid = Binder.getCallingUid();
9070        long ident = Binder.clearCallingIdentity();
9071
9072        synchronized(this) {
9073            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9074            try {
9075                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9076
9077                final int N = mRecentTasks.size();
9078                for (int i = 0; i < N; i++) {
9079                    TaskRecord tr = mRecentTasks.get(i);
9080                    // Skip tasks that do not match the caller.  We don't need to verify
9081                    // callingPackage, because we are also limiting to callingUid and know
9082                    // that will limit to the correct security sandbox.
9083                    if (tr.effectiveUid != callingUid) {
9084                        continue;
9085                    }
9086                    Intent intent = tr.getBaseIntent();
9087                    if (intent == null ||
9088                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9089                        continue;
9090                    }
9091                    ActivityManager.RecentTaskInfo taskInfo =
9092                            createRecentTaskInfoFromTaskRecord(tr);
9093                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9094                    list.add(taskImpl);
9095                }
9096            } finally {
9097                Binder.restoreCallingIdentity(ident);
9098            }
9099            return list;
9100        }
9101    }
9102
9103    @Override
9104    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9105        final int callingUid = Binder.getCallingUid();
9106        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9107
9108        synchronized(this) {
9109            if (DEBUG_ALL) Slog.v(
9110                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9111
9112            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9113                    callingUid);
9114
9115            // TODO: Improve with MRU list from all ActivityStacks.
9116            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9117        }
9118
9119        return list;
9120    }
9121
9122    /**
9123     * Creates a new RecentTaskInfo from a TaskRecord.
9124     */
9125    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9126        // Update the task description to reflect any changes in the task stack
9127        tr.updateTaskDescription();
9128
9129        // Compose the recent task info
9130        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9131        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9132        rti.persistentId = tr.taskId;
9133        rti.baseIntent = new Intent(tr.getBaseIntent());
9134        rti.origActivity = tr.origActivity;
9135        rti.realActivity = tr.realActivity;
9136        rti.description = tr.lastDescription;
9137        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9138        rti.userId = tr.userId;
9139        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9140        rti.firstActiveTime = tr.firstActiveTime;
9141        rti.lastActiveTime = tr.lastActiveTime;
9142        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9143        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9144        rti.numActivities = 0;
9145        if (tr.mBounds != null) {
9146            rti.bounds = new Rect(tr.mBounds);
9147        }
9148        rti.isDockable = tr.canGoInDockedStack();
9149        rti.resizeMode = tr.mResizeMode;
9150
9151        ActivityRecord base = null;
9152        ActivityRecord top = null;
9153        ActivityRecord tmp;
9154
9155        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9156            tmp = tr.mActivities.get(i);
9157            if (tmp.finishing) {
9158                continue;
9159            }
9160            base = tmp;
9161            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9162                top = base;
9163            }
9164            rti.numActivities++;
9165        }
9166
9167        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9168        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9169
9170        return rti;
9171    }
9172
9173    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9174        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9175                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9176        if (!allowed) {
9177            if (checkPermission(android.Manifest.permission.GET_TASKS,
9178                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9179                // Temporary compatibility: some existing apps on the system image may
9180                // still be requesting the old permission and not switched to the new
9181                // one; if so, we'll still allow them full access.  This means we need
9182                // to see if they are holding the old permission and are a system app.
9183                try {
9184                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9185                        allowed = true;
9186                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9187                                + " is using old GET_TASKS but privileged; allowing");
9188                    }
9189                } catch (RemoteException e) {
9190                }
9191            }
9192        }
9193        if (!allowed) {
9194            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9195                    + " does not hold REAL_GET_TASKS; limiting output");
9196        }
9197        return allowed;
9198    }
9199
9200    @Override
9201    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9202            int userId) {
9203        final int callingUid = Binder.getCallingUid();
9204        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9205                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9206
9207        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9208        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9209        synchronized (this) {
9210            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9211                    callingUid);
9212            final boolean detailed = checkCallingPermission(
9213                    android.Manifest.permission.GET_DETAILED_TASKS)
9214                    == PackageManager.PERMISSION_GRANTED;
9215
9216            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9217                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9218                return ParceledListSlice.emptyList();
9219            }
9220            mRecentTasks.loadUserRecentsLocked(userId);
9221
9222            final int recentsCount = mRecentTasks.size();
9223            ArrayList<ActivityManager.RecentTaskInfo> res =
9224                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9225
9226            final Set<Integer> includedUsers;
9227            if (includeProfiles) {
9228                includedUsers = mUserController.getProfileIds(userId);
9229            } else {
9230                includedUsers = new HashSet<>();
9231            }
9232            includedUsers.add(Integer.valueOf(userId));
9233
9234            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9235                TaskRecord tr = mRecentTasks.get(i);
9236                // Only add calling user or related users recent tasks
9237                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9238                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9239                    continue;
9240                }
9241
9242                if (tr.realActivitySuspended) {
9243                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9244                    continue;
9245                }
9246
9247                // Return the entry if desired by the caller.  We always return
9248                // the first entry, because callers always expect this to be the
9249                // foreground app.  We may filter others if the caller has
9250                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9251                // we should exclude the entry.
9252
9253                if (i == 0
9254                        || withExcluded
9255                        || (tr.intent == null)
9256                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9257                                == 0)) {
9258                    if (!allowed) {
9259                        // If the caller doesn't have the GET_TASKS permission, then only
9260                        // allow them to see a small subset of tasks -- their own and home.
9261                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9262                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9263                            continue;
9264                        }
9265                    }
9266                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9267                        if (tr.stack != null && tr.stack.isHomeStack()) {
9268                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9269                                    "Skipping, home stack task: " + tr);
9270                            continue;
9271                        }
9272                    }
9273                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9274                        final ActivityStack stack = tr.stack;
9275                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9276                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9277                                    "Skipping, top task in docked stack: " + tr);
9278                            continue;
9279                        }
9280                    }
9281                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9282                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9283                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9284                                    "Skipping, pinned stack task: " + tr);
9285                            continue;
9286                        }
9287                    }
9288                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9289                        // Don't include auto remove tasks that are finished or finishing.
9290                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9291                                "Skipping, auto-remove without activity: " + tr);
9292                        continue;
9293                    }
9294                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9295                            && !tr.isAvailable) {
9296                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9297                                "Skipping, unavail real act: " + tr);
9298                        continue;
9299                    }
9300
9301                    if (!tr.mUserSetupComplete) {
9302                        // Don't include task launched while user is not done setting-up.
9303                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9304                                "Skipping, user setup not complete: " + tr);
9305                        continue;
9306                    }
9307
9308                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9309                    if (!detailed) {
9310                        rti.baseIntent.replaceExtras((Bundle)null);
9311                    }
9312
9313                    res.add(rti);
9314                    maxNum--;
9315                }
9316            }
9317            return new ParceledListSlice<>(res);
9318        }
9319    }
9320
9321    @Override
9322    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9323        synchronized (this) {
9324            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9325                    "getTaskThumbnail()");
9326            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9327                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9328            if (tr != null) {
9329                return tr.getTaskThumbnailLocked();
9330            }
9331        }
9332        return null;
9333    }
9334
9335    @Override
9336    public int addAppTask(IBinder activityToken, Intent intent,
9337            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9338        final int callingUid = Binder.getCallingUid();
9339        final long callingIdent = Binder.clearCallingIdentity();
9340
9341        try {
9342            synchronized (this) {
9343                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9344                if (r == null) {
9345                    throw new IllegalArgumentException("Activity does not exist; token="
9346                            + activityToken);
9347                }
9348                ComponentName comp = intent.getComponent();
9349                if (comp == null) {
9350                    throw new IllegalArgumentException("Intent " + intent
9351                            + " must specify explicit component");
9352                }
9353                if (thumbnail.getWidth() != mThumbnailWidth
9354                        || thumbnail.getHeight() != mThumbnailHeight) {
9355                    throw new IllegalArgumentException("Bad thumbnail size: got "
9356                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9357                            + mThumbnailWidth + "x" + mThumbnailHeight);
9358                }
9359                if (intent.getSelector() != null) {
9360                    intent.setSelector(null);
9361                }
9362                if (intent.getSourceBounds() != null) {
9363                    intent.setSourceBounds(null);
9364                }
9365                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9366                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9367                        // The caller has added this as an auto-remove task...  that makes no
9368                        // sense, so turn off auto-remove.
9369                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9370                    }
9371                }
9372                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9373                    mLastAddedTaskActivity = null;
9374                }
9375                ActivityInfo ainfo = mLastAddedTaskActivity;
9376                if (ainfo == null) {
9377                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9378                            comp, 0, UserHandle.getUserId(callingUid));
9379                    if (ainfo.applicationInfo.uid != callingUid) {
9380                        throw new SecurityException(
9381                                "Can't add task for another application: target uid="
9382                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9383                    }
9384                }
9385
9386                // Use the full screen as the context for the task thumbnail
9387                final Point displaySize = new Point();
9388                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9389                r.task.stack.getDisplaySize(displaySize);
9390                thumbnailInfo.taskWidth = displaySize.x;
9391                thumbnailInfo.taskHeight = displaySize.y;
9392                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9393
9394                TaskRecord task = new TaskRecord(this,
9395                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9396                        ainfo, intent, description, thumbnailInfo);
9397
9398                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9399                if (trimIdx >= 0) {
9400                    // If this would have caused a trim, then we'll abort because that
9401                    // means it would be added at the end of the list but then just removed.
9402                    return INVALID_TASK_ID;
9403                }
9404
9405                final int N = mRecentTasks.size();
9406                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9407                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9408                    tr.removedFromRecents();
9409                }
9410
9411                task.inRecents = true;
9412                mRecentTasks.add(task);
9413                r.task.stack.addTask(task, false, "addAppTask");
9414
9415                task.setLastThumbnailLocked(thumbnail);
9416                task.freeLastThumbnail();
9417
9418                return task.taskId;
9419            }
9420        } finally {
9421            Binder.restoreCallingIdentity(callingIdent);
9422        }
9423    }
9424
9425    @Override
9426    public Point getAppTaskThumbnailSize() {
9427        synchronized (this) {
9428            return new Point(mThumbnailWidth,  mThumbnailHeight);
9429        }
9430    }
9431
9432    @Override
9433    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9434        synchronized (this) {
9435            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9436            if (r != null) {
9437                r.setTaskDescription(td);
9438                r.task.updateTaskDescription();
9439            }
9440        }
9441    }
9442
9443    @Override
9444    public void setTaskResizeable(int taskId, int resizeableMode) {
9445        synchronized (this) {
9446            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9447                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9448            if (task == null) {
9449                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9450                return;
9451            }
9452            if (task.mResizeMode != resizeableMode) {
9453                task.mResizeMode = resizeableMode;
9454                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9455                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9456                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9457            }
9458        }
9459    }
9460
9461    @Override
9462    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9463        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9464        long ident = Binder.clearCallingIdentity();
9465        try {
9466            synchronized (this) {
9467                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9468                if (task == null) {
9469                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9470                    return;
9471                }
9472                int stackId = task.stack.mStackId;
9473                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9474                // in crop windows resize mode or if the task size is affected by the docked stack
9475                // changing size. No need to update configuration.
9476                if (bounds != null && task.inCropWindowsResizeMode()
9477                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9478                    mWindowManager.scrollTask(task.taskId, bounds);
9479                    return;
9480                }
9481
9482                // Place the task in the right stack if it isn't there already based on
9483                // the requested bounds.
9484                // The stack transition logic is:
9485                // - a null bounds on a freeform task moves that task to fullscreen
9486                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9487                //   that task to freeform
9488                // - otherwise the task is not moved
9489                if (!StackId.isTaskResizeAllowed(stackId)) {
9490                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9491                }
9492                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9493                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9494                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9495                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9496                }
9497                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9498                if (stackId != task.stack.mStackId) {
9499                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9500                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9501                    preserveWindow = false;
9502                }
9503
9504                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9505                        false /* deferResume */);
9506            }
9507        } finally {
9508            Binder.restoreCallingIdentity(ident);
9509        }
9510    }
9511
9512    @Override
9513    public Rect getTaskBounds(int taskId) {
9514        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9515        long ident = Binder.clearCallingIdentity();
9516        Rect rect = new Rect();
9517        try {
9518            synchronized (this) {
9519                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9520                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9521                if (task == null) {
9522                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9523                    return rect;
9524                }
9525                if (task.stack != null) {
9526                    // Return the bounds from window manager since it will be adjusted for various
9527                    // things like the presense of a docked stack for tasks that aren't resizeable.
9528                    mWindowManager.getTaskBounds(task.taskId, rect);
9529                } else {
9530                    // Task isn't in window manager yet since it isn't associated with a stack.
9531                    // Return the persist value from activity manager
9532                    if (task.mBounds != null) {
9533                        rect.set(task.mBounds);
9534                    } else if (task.mLastNonFullscreenBounds != null) {
9535                        rect.set(task.mLastNonFullscreenBounds);
9536                    }
9537                }
9538            }
9539        } finally {
9540            Binder.restoreCallingIdentity(ident);
9541        }
9542        return rect;
9543    }
9544
9545    @Override
9546    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9547        if (userId != UserHandle.getCallingUserId()) {
9548            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9549                    "getTaskDescriptionIcon");
9550        }
9551        final File passedIconFile = new File(filePath);
9552        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9553                passedIconFile.getName());
9554        if (!legitIconFile.getPath().equals(filePath)
9555                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9556            throw new IllegalArgumentException("Bad file path: " + filePath
9557                    + " passed for userId " + userId);
9558        }
9559        return mRecentTasks.getTaskDescriptionIcon(filePath);
9560    }
9561
9562    @Override
9563    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9564            throws RemoteException {
9565        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9566                opts.getCustomInPlaceResId() == 0) {
9567            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9568                    "with valid animation");
9569        }
9570        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9571        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9572                opts.getCustomInPlaceResId());
9573        mWindowManager.executeAppTransition();
9574    }
9575
9576    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9577            boolean removeFromRecents) {
9578        if (removeFromRecents) {
9579            mRecentTasks.remove(tr);
9580            tr.removedFromRecents();
9581        }
9582        ComponentName component = tr.getBaseIntent().getComponent();
9583        if (component == null) {
9584            Slog.w(TAG, "No component for base intent of task: " + tr);
9585            return;
9586        }
9587
9588        // Find any running services associated with this app and stop if needed.
9589        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9590
9591        if (!killProcess) {
9592            return;
9593        }
9594
9595        // Determine if the process(es) for this task should be killed.
9596        final String pkg = component.getPackageName();
9597        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9598        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9599        for (int i = 0; i < pmap.size(); i++) {
9600
9601            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9602            for (int j = 0; j < uids.size(); j++) {
9603                ProcessRecord proc = uids.valueAt(j);
9604                if (proc.userId != tr.userId) {
9605                    // Don't kill process for a different user.
9606                    continue;
9607                }
9608                if (proc == mHomeProcess) {
9609                    // Don't kill the home process along with tasks from the same package.
9610                    continue;
9611                }
9612                if (!proc.pkgList.containsKey(pkg)) {
9613                    // Don't kill process that is not associated with this task.
9614                    continue;
9615                }
9616
9617                for (int k = 0; k < proc.activities.size(); k++) {
9618                    TaskRecord otherTask = proc.activities.get(k).task;
9619                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9620                        // Don't kill process(es) that has an activity in a different task that is
9621                        // also in recents.
9622                        return;
9623                    }
9624                }
9625
9626                if (proc.foregroundServices) {
9627                    // Don't kill process(es) with foreground service.
9628                    return;
9629                }
9630
9631                // Add process to kill list.
9632                procsToKill.add(proc);
9633            }
9634        }
9635
9636        // Kill the running processes.
9637        for (int i = 0; i < procsToKill.size(); i++) {
9638            ProcessRecord pr = procsToKill.get(i);
9639            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9640                    && pr.curReceivers.isEmpty()) {
9641                pr.kill("remove task", true);
9642            } else {
9643                // We delay killing processes that are not in the background or running a receiver.
9644                pr.waitingToKill = "remove task";
9645            }
9646        }
9647    }
9648
9649    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9650        // Remove all tasks with activities in the specified package from the list of recent tasks
9651        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9652            TaskRecord tr = mRecentTasks.get(i);
9653            if (tr.userId != userId) continue;
9654
9655            ComponentName cn = tr.intent.getComponent();
9656            if (cn != null && cn.getPackageName().equals(packageName)) {
9657                // If the package name matches, remove the task.
9658                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9659            }
9660        }
9661    }
9662
9663    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9664            int userId) {
9665
9666        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9667            TaskRecord tr = mRecentTasks.get(i);
9668            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9669                continue;
9670            }
9671
9672            ComponentName cn = tr.intent.getComponent();
9673            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9674                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9675            if (sameComponent) {
9676                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9677            }
9678        }
9679    }
9680
9681    /**
9682     * Removes the task with the specified task id.
9683     *
9684     * @param taskId Identifier of the task to be removed.
9685     * @param killProcess Kill any process associated with the task if possible.
9686     * @param removeFromRecents Whether to also remove the task from recents.
9687     * @return Returns true if the given task was found and removed.
9688     */
9689    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9690            boolean removeFromRecents) {
9691        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9692                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9693        if (tr != null) {
9694            tr.removeTaskActivitiesLocked();
9695            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9696            if (tr.isPersistable) {
9697                notifyTaskPersisterLocked(null, true);
9698            }
9699            return true;
9700        }
9701        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9702        return false;
9703    }
9704
9705    @Override
9706    public void removeStack(int stackId) {
9707        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9708        if (stackId == HOME_STACK_ID) {
9709            throw new IllegalArgumentException("Removing home stack is not allowed.");
9710        }
9711
9712        synchronized (this) {
9713            final long ident = Binder.clearCallingIdentity();
9714            try {
9715                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9716                if (stack == null) {
9717                    return;
9718                }
9719                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9720                for (int i = tasks.size() - 1; i >= 0; i--) {
9721                    removeTaskByIdLocked(
9722                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9723                }
9724            } finally {
9725                Binder.restoreCallingIdentity(ident);
9726            }
9727        }
9728    }
9729
9730    @Override
9731    public boolean removeTask(int taskId) {
9732        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9733        synchronized (this) {
9734            final long ident = Binder.clearCallingIdentity();
9735            try {
9736                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9737            } finally {
9738                Binder.restoreCallingIdentity(ident);
9739            }
9740        }
9741    }
9742
9743    /**
9744     * TODO: Add mController hook
9745     */
9746    @Override
9747    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9748        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9749
9750        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9751        synchronized(this) {
9752            moveTaskToFrontLocked(taskId, flags, bOptions);
9753        }
9754    }
9755
9756    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9757        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9758
9759        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9760                Binder.getCallingUid(), -1, -1, "Task to front")) {
9761            ActivityOptions.abort(options);
9762            return;
9763        }
9764        final long origId = Binder.clearCallingIdentity();
9765        try {
9766            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9767            if (task == null) {
9768                Slog.d(TAG, "Could not find task for id: "+ taskId);
9769                return;
9770            }
9771            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9772                mStackSupervisor.showLockTaskToast();
9773                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9774                return;
9775            }
9776            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9777            if (prev != null && prev.isRecentsActivity()) {
9778                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9779            }
9780            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9781                    false /* forceNonResizable */);
9782        } finally {
9783            Binder.restoreCallingIdentity(origId);
9784        }
9785        ActivityOptions.abort(options);
9786    }
9787
9788    /**
9789     * Moves an activity, and all of the other activities within the same task, to the bottom
9790     * of the history stack.  The activity's order within the task is unchanged.
9791     *
9792     * @param token A reference to the activity we wish to move
9793     * @param nonRoot If false then this only works if the activity is the root
9794     *                of a task; if true it will work for any activity in a task.
9795     * @return Returns true if the move completed, false if not.
9796     */
9797    @Override
9798    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9799        enforceNotIsolatedCaller("moveActivityTaskToBack");
9800        synchronized(this) {
9801            final long origId = Binder.clearCallingIdentity();
9802            try {
9803                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9804                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9805                if (task != null) {
9806                    if (mStackSupervisor.isLockedTask(task)) {
9807                        mStackSupervisor.showLockTaskToast();
9808                        return false;
9809                    }
9810                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9811                }
9812            } finally {
9813                Binder.restoreCallingIdentity(origId);
9814            }
9815        }
9816        return false;
9817    }
9818
9819    @Override
9820    public void moveTaskBackwards(int task) {
9821        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9822                "moveTaskBackwards()");
9823
9824        synchronized(this) {
9825            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9826                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9827                return;
9828            }
9829            final long origId = Binder.clearCallingIdentity();
9830            moveTaskBackwardsLocked(task);
9831            Binder.restoreCallingIdentity(origId);
9832        }
9833    }
9834
9835    private final void moveTaskBackwardsLocked(int task) {
9836        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9837    }
9838
9839    @Override
9840    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9841            IActivityContainerCallback callback) throws RemoteException {
9842        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9843        synchronized (this) {
9844            if (parentActivityToken == null) {
9845                throw new IllegalArgumentException("parent token must not be null");
9846            }
9847            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9848            if (r == null) {
9849                return null;
9850            }
9851            if (callback == null) {
9852                throw new IllegalArgumentException("callback must not be null");
9853            }
9854            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9855        }
9856    }
9857
9858    @Override
9859    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9860        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9861        synchronized (this) {
9862            mStackSupervisor.deleteActivityContainer(container);
9863        }
9864    }
9865
9866    @Override
9867    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9868        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9869        synchronized (this) {
9870            final int stackId = mStackSupervisor.getNextStackId();
9871            final ActivityStack stack =
9872                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9873            if (stack == null) {
9874                return null;
9875            }
9876            return stack.mActivityContainer;
9877        }
9878    }
9879
9880    @Override
9881    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9882        synchronized (this) {
9883            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9884            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9885                return stack.mActivityContainer.getDisplayId();
9886            }
9887            return Display.DEFAULT_DISPLAY;
9888        }
9889    }
9890
9891    @Override
9892    public int getActivityStackId(IBinder token) throws RemoteException {
9893        synchronized (this) {
9894            ActivityStack stack = ActivityRecord.getStackLocked(token);
9895            if (stack == null) {
9896                return INVALID_STACK_ID;
9897            }
9898            return stack.mStackId;
9899        }
9900    }
9901
9902    @Override
9903    public void exitFreeformMode(IBinder token) throws RemoteException {
9904        synchronized (this) {
9905            long ident = Binder.clearCallingIdentity();
9906            try {
9907                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9908                if (r == null) {
9909                    throw new IllegalArgumentException(
9910                            "exitFreeformMode: No activity record matching token=" + token);
9911                }
9912                final ActivityStack stack = r.getStackLocked(token);
9913                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9914                    throw new IllegalStateException(
9915                            "exitFreeformMode: You can only go fullscreen from freeform.");
9916                }
9917                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9918                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9919                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9920            } finally {
9921                Binder.restoreCallingIdentity(ident);
9922            }
9923        }
9924    }
9925
9926    @Override
9927    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9928        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9929        if (stackId == HOME_STACK_ID) {
9930            throw new IllegalArgumentException(
9931                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9932        }
9933        synchronized (this) {
9934            long ident = Binder.clearCallingIdentity();
9935            try {
9936                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9937                        + " to stackId=" + stackId + " toTop=" + toTop);
9938                if (stackId == DOCKED_STACK_ID) {
9939                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9940                            null /* initialBounds */);
9941                }
9942                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9943                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9944                if (result && stackId == DOCKED_STACK_ID) {
9945                    // If task moved to docked stack - show recents if needed.
9946                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9947                            "moveTaskToDockedStack");
9948                }
9949            } finally {
9950                Binder.restoreCallingIdentity(ident);
9951            }
9952        }
9953    }
9954
9955    @Override
9956    public void swapDockedAndFullscreenStack() throws RemoteException {
9957        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9958        synchronized (this) {
9959            long ident = Binder.clearCallingIdentity();
9960            try {
9961                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9962                        FULLSCREEN_WORKSPACE_STACK_ID);
9963                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9964                        : null;
9965                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9966                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9967                        : null;
9968                if (topTask == null || tasks == null || tasks.size() == 0) {
9969                    Slog.w(TAG,
9970                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9971                    return;
9972                }
9973
9974                // TODO: App transition
9975                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9976
9977                // Defer the resume so resume/pausing while moving stacks is dangerous.
9978                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9979                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9980                        ANIMATE, true /* deferResume */);
9981                final int size = tasks.size();
9982                for (int i = 0; i < size; i++) {
9983                    final int id = tasks.get(i).taskId;
9984                    if (id == topTask.taskId) {
9985                        continue;
9986                    }
9987                    mStackSupervisor.moveTaskToStackLocked(id,
9988                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9989                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9990                }
9991
9992                // Because we deferred the resume, to avoid conflicts with stack switches while
9993                // resuming, we need to do it after all the tasks are moved.
9994                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9995                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9996
9997                mWindowManager.executeAppTransition();
9998            } finally {
9999                Binder.restoreCallingIdentity(ident);
10000            }
10001        }
10002    }
10003
10004    /**
10005     * Moves the input task to the docked stack.
10006     *
10007     * @param taskId Id of task to move.
10008     * @param createMode The mode the docked stack should be created in if it doesn't exist
10009     *                   already. See
10010     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10011     *                   and
10012     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10013     * @param toTop If the task and stack should be moved to the top.
10014     * @param animate Whether we should play an animation for the moving the task
10015     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10016     *                      docked stack. Pass {@code null} to use default bounds.
10017     */
10018    @Override
10019    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10020            Rect initialBounds, boolean moveHomeStackFront) {
10021        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10022        synchronized (this) {
10023            long ident = Binder.clearCallingIdentity();
10024            try {
10025                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10026                        + " to createMode=" + createMode + " toTop=" + toTop);
10027                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10028                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10029                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10030                        animate, DEFER_RESUME);
10031                if (moved) {
10032                    if (moveHomeStackFront) {
10033                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10034                    }
10035                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10036                }
10037                return moved;
10038            } finally {
10039                Binder.restoreCallingIdentity(ident);
10040            }
10041        }
10042    }
10043
10044    /**
10045     * Moves the top activity in the input stackId to the pinned stack.
10046     *
10047     * @param stackId Id of stack to move the top activity to pinned stack.
10048     * @param bounds Bounds to use for pinned stack.
10049     *
10050     * @return True if the top activity of the input stack was successfully moved to the pinned
10051     *          stack.
10052     */
10053    @Override
10054    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10055        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10056        synchronized (this) {
10057            if (!mSupportsPictureInPicture) {
10058                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10059                        + "Device doesn't support picture-in-pciture mode");
10060            }
10061
10062            long ident = Binder.clearCallingIdentity();
10063            try {
10064                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10065            } finally {
10066                Binder.restoreCallingIdentity(ident);
10067            }
10068        }
10069    }
10070
10071    @Override
10072    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10073            boolean preserveWindows, boolean animate, int animationDuration) {
10074        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10075        long ident = Binder.clearCallingIdentity();
10076        try {
10077            synchronized (this) {
10078                if (animate) {
10079                    if (stackId == PINNED_STACK_ID) {
10080                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10081                    } else {
10082                        throw new IllegalArgumentException("Stack: " + stackId
10083                                + " doesn't support animated resize.");
10084                    }
10085                } else {
10086                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10087                            null /* tempTaskInsetBounds */, preserveWindows,
10088                            allowResizeInDockedMode, !DEFER_RESUME);
10089                }
10090            }
10091        } finally {
10092            Binder.restoreCallingIdentity(ident);
10093        }
10094    }
10095
10096    @Override
10097    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10098            Rect tempDockedTaskInsetBounds,
10099            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10101                "resizeDockedStack()");
10102        long ident = Binder.clearCallingIdentity();
10103        try {
10104            synchronized (this) {
10105                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10106                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10107                        PRESERVE_WINDOWS);
10108            }
10109        } finally {
10110            Binder.restoreCallingIdentity(ident);
10111        }
10112    }
10113
10114    @Override
10115    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10116        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10117                "resizePinnedStack()");
10118        final long ident = Binder.clearCallingIdentity();
10119        try {
10120            synchronized (this) {
10121                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10122            }
10123        } finally {
10124            Binder.restoreCallingIdentity(ident);
10125        }
10126    }
10127
10128    @Override
10129    public void positionTaskInStack(int taskId, int stackId, int position) {
10130        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10131        if (stackId == HOME_STACK_ID) {
10132            throw new IllegalArgumentException(
10133                    "positionTaskInStack: Attempt to change the position of task "
10134                    + taskId + " in/to home stack");
10135        }
10136        synchronized (this) {
10137            long ident = Binder.clearCallingIdentity();
10138            try {
10139                if (DEBUG_STACK) Slog.d(TAG_STACK,
10140                        "positionTaskInStack: positioning task=" + taskId
10141                        + " in stackId=" + stackId + " at position=" + position);
10142                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10143            } finally {
10144                Binder.restoreCallingIdentity(ident);
10145            }
10146        }
10147    }
10148
10149    @Override
10150    public List<StackInfo> getAllStackInfos() {
10151        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10152        long ident = Binder.clearCallingIdentity();
10153        try {
10154            synchronized (this) {
10155                return mStackSupervisor.getAllStackInfosLocked();
10156            }
10157        } finally {
10158            Binder.restoreCallingIdentity(ident);
10159        }
10160    }
10161
10162    @Override
10163    public StackInfo getStackInfo(int stackId) {
10164        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10165        long ident = Binder.clearCallingIdentity();
10166        try {
10167            synchronized (this) {
10168                return mStackSupervisor.getStackInfoLocked(stackId);
10169            }
10170        } finally {
10171            Binder.restoreCallingIdentity(ident);
10172        }
10173    }
10174
10175    @Override
10176    public boolean isInHomeStack(int taskId) {
10177        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10178        long ident = Binder.clearCallingIdentity();
10179        try {
10180            synchronized (this) {
10181                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10182                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10183                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10184            }
10185        } finally {
10186            Binder.restoreCallingIdentity(ident);
10187        }
10188    }
10189
10190    @Override
10191    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10192        synchronized(this) {
10193            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10194        }
10195    }
10196
10197    @Override
10198    public void updateDeviceOwner(String packageName) {
10199        final int callingUid = Binder.getCallingUid();
10200        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10201            throw new SecurityException("updateDeviceOwner called from non-system process");
10202        }
10203        synchronized (this) {
10204            mDeviceOwnerName = packageName;
10205        }
10206    }
10207
10208    @Override
10209    public void updateLockTaskPackages(int userId, String[] packages) {
10210        final int callingUid = Binder.getCallingUid();
10211        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10212            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10213                    "updateLockTaskPackages()");
10214        }
10215        synchronized (this) {
10216            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10217                    Arrays.toString(packages));
10218            mLockTaskPackages.put(userId, packages);
10219            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10220        }
10221    }
10222
10223
10224    void startLockTaskModeLocked(TaskRecord task) {
10225        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10226        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10227            return;
10228        }
10229
10230        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10231        // is initiated by system after the pinning request was shown and locked mode is initiated
10232        // by an authorized app directly
10233        final int callingUid = Binder.getCallingUid();
10234        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10235        long ident = Binder.clearCallingIdentity();
10236        try {
10237            if (!isSystemInitiated) {
10238                task.mLockTaskUid = callingUid;
10239                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10240                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10241                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10242                    StatusBarManagerInternal statusBarManager =
10243                            LocalServices.getService(StatusBarManagerInternal.class);
10244                    if (statusBarManager != null) {
10245                        statusBarManager.showScreenPinningRequest(task.taskId);
10246                    }
10247                    return;
10248                }
10249
10250                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10251                if (stack == null || task != stack.topTask()) {
10252                    throw new IllegalArgumentException("Invalid task, not in foreground");
10253                }
10254            }
10255            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10256                    "Locking fully");
10257            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10258                    ActivityManager.LOCK_TASK_MODE_PINNED :
10259                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10260                    "startLockTask", true);
10261        } finally {
10262            Binder.restoreCallingIdentity(ident);
10263        }
10264    }
10265
10266    @Override
10267    public void startLockTaskMode(int taskId) {
10268        synchronized (this) {
10269            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10270            if (task != null) {
10271                startLockTaskModeLocked(task);
10272            }
10273        }
10274    }
10275
10276    @Override
10277    public void startLockTaskMode(IBinder token) {
10278        synchronized (this) {
10279            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10280            if (r == null) {
10281                return;
10282            }
10283            final TaskRecord task = r.task;
10284            if (task != null) {
10285                startLockTaskModeLocked(task);
10286            }
10287        }
10288    }
10289
10290    @Override
10291    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10292        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10293        // This makes inner call to look as if it was initiated by system.
10294        long ident = Binder.clearCallingIdentity();
10295        try {
10296            synchronized (this) {
10297                startLockTaskMode(taskId);
10298            }
10299        } finally {
10300            Binder.restoreCallingIdentity(ident);
10301        }
10302    }
10303
10304    @Override
10305    public void stopLockTaskMode() {
10306        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10307        if (lockTask == null) {
10308            // Our work here is done.
10309            return;
10310        }
10311
10312        final int callingUid = Binder.getCallingUid();
10313        final int lockTaskUid = lockTask.mLockTaskUid;
10314        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10315        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10316            // Done.
10317            return;
10318        } else {
10319            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10320            // It is possible lockTaskMode was started by the system process because
10321            // android:lockTaskMode is set to a locking value in the application manifest
10322            // instead of the app calling startLockTaskMode. In this case
10323            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10324            // {@link TaskRecord.effectiveUid} instead. Also caller with
10325            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10326            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10327                    && callingUid != lockTaskUid
10328                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10329                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10330                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10331            }
10332        }
10333        long ident = Binder.clearCallingIdentity();
10334        try {
10335            Log.d(TAG, "stopLockTaskMode");
10336            // Stop lock task
10337            synchronized (this) {
10338                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10339                        "stopLockTask", true);
10340            }
10341            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10342            if (tm != null) {
10343                tm.showInCallScreen(false);
10344            }
10345        } finally {
10346            Binder.restoreCallingIdentity(ident);
10347        }
10348    }
10349
10350    /**
10351     * This API should be called by SystemUI only when user perform certain action to dismiss
10352     * lock task mode. We should only dismiss pinned lock task mode in this case.
10353     */
10354    @Override
10355    public void stopSystemLockTaskMode() throws RemoteException {
10356        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10357            stopLockTaskMode();
10358        } else {
10359            mStackSupervisor.showLockTaskToast();
10360        }
10361    }
10362
10363    @Override
10364    public boolean isInLockTaskMode() {
10365        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10366    }
10367
10368    @Override
10369    public int getLockTaskModeState() {
10370        synchronized (this) {
10371            return mStackSupervisor.getLockTaskModeState();
10372        }
10373    }
10374
10375    @Override
10376    public void showLockTaskEscapeMessage(IBinder token) {
10377        synchronized (this) {
10378            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10379            if (r == null) {
10380                return;
10381            }
10382            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10383        }
10384    }
10385
10386    // =========================================================
10387    // CONTENT PROVIDERS
10388    // =========================================================
10389
10390    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10391        List<ProviderInfo> providers = null;
10392        try {
10393            providers = AppGlobals.getPackageManager()
10394                    .queryContentProviders(app.processName, app.uid,
10395                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10396                                    | MATCH_DEBUG_TRIAGED_MISSING)
10397                    .getList();
10398        } catch (RemoteException ex) {
10399        }
10400        if (DEBUG_MU) Slog.v(TAG_MU,
10401                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10402        int userId = app.userId;
10403        if (providers != null) {
10404            int N = providers.size();
10405            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10406            for (int i=0; i<N; i++) {
10407                // TODO: keep logic in sync with installEncryptionUnawareProviders
10408                ProviderInfo cpi =
10409                    (ProviderInfo)providers.get(i);
10410                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10411                        cpi.name, cpi.flags);
10412                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10413                    // This is a singleton provider, but a user besides the
10414                    // default user is asking to initialize a process it runs
10415                    // in...  well, no, it doesn't actually run in this process,
10416                    // it runs in the process of the default user.  Get rid of it.
10417                    providers.remove(i);
10418                    N--;
10419                    i--;
10420                    continue;
10421                }
10422
10423                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10424                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10425                if (cpr == null) {
10426                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10427                    mProviderMap.putProviderByClass(comp, cpr);
10428                }
10429                if (DEBUG_MU) Slog.v(TAG_MU,
10430                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10431                app.pubProviders.put(cpi.name, cpr);
10432                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10433                    // Don't add this if it is a platform component that is marked
10434                    // to run in multiple processes, because this is actually
10435                    // part of the framework so doesn't make sense to track as a
10436                    // separate apk in the process.
10437                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10438                            mProcessStats);
10439                }
10440                notifyPackageUse(cpi.applicationInfo.packageName,
10441                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10442            }
10443        }
10444        return providers;
10445    }
10446
10447    /**
10448     * Check if the calling UID has a possible chance at accessing the provider
10449     * at the given authority and user.
10450     */
10451    public String checkContentProviderAccess(String authority, int userId) {
10452        if (userId == UserHandle.USER_ALL) {
10453            mContext.enforceCallingOrSelfPermission(
10454                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10455            userId = UserHandle.getCallingUserId();
10456        }
10457
10458        ProviderInfo cpi = null;
10459        try {
10460            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10461                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10462                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10463                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10464                    userId);
10465        } catch (RemoteException ignored) {
10466        }
10467        if (cpi == null) {
10468            // TODO: make this an outright failure in a future platform release;
10469            // until then anonymous content notifications are unprotected
10470            //return "Failed to find provider " + authority + " for user " + userId;
10471            return null;
10472        }
10473
10474        ProcessRecord r = null;
10475        synchronized (mPidsSelfLocked) {
10476            r = mPidsSelfLocked.get(Binder.getCallingPid());
10477        }
10478        if (r == null) {
10479            return "Failed to find PID " + Binder.getCallingPid();
10480        }
10481
10482        synchronized (this) {
10483            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10484        }
10485    }
10486
10487    /**
10488     * Check if {@link ProcessRecord} has a possible chance at accessing the
10489     * given {@link ProviderInfo}. Final permission checking is always done
10490     * in {@link ContentProvider}.
10491     */
10492    private final String checkContentProviderPermissionLocked(
10493            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10494        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10495        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10496        boolean checkedGrants = false;
10497        if (checkUser) {
10498            // Looking for cross-user grants before enforcing the typical cross-users permissions
10499            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10500            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10501                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10502                    return null;
10503                }
10504                checkedGrants = true;
10505            }
10506            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10507                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10508            if (userId != tmpTargetUserId) {
10509                // When we actually went to determine the final targer user ID, this ended
10510                // up different than our initial check for the authority.  This is because
10511                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10512                // SELF.  So we need to re-check the grants again.
10513                checkedGrants = false;
10514            }
10515        }
10516        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10517                cpi.applicationInfo.uid, cpi.exported)
10518                == PackageManager.PERMISSION_GRANTED) {
10519            return null;
10520        }
10521        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10522                cpi.applicationInfo.uid, cpi.exported)
10523                == PackageManager.PERMISSION_GRANTED) {
10524            return null;
10525        }
10526
10527        PathPermission[] pps = cpi.pathPermissions;
10528        if (pps != null) {
10529            int i = pps.length;
10530            while (i > 0) {
10531                i--;
10532                PathPermission pp = pps[i];
10533                String pprperm = pp.getReadPermission();
10534                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10535                        cpi.applicationInfo.uid, cpi.exported)
10536                        == PackageManager.PERMISSION_GRANTED) {
10537                    return null;
10538                }
10539                String ppwperm = pp.getWritePermission();
10540                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10541                        cpi.applicationInfo.uid, cpi.exported)
10542                        == PackageManager.PERMISSION_GRANTED) {
10543                    return null;
10544                }
10545            }
10546        }
10547        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10548            return null;
10549        }
10550
10551        String msg;
10552        if (!cpi.exported) {
10553            msg = "Permission Denial: opening provider " + cpi.name
10554                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10555                    + ", uid=" + callingUid + ") that is not exported from uid "
10556                    + cpi.applicationInfo.uid;
10557        } else {
10558            msg = "Permission Denial: opening provider " + cpi.name
10559                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10560                    + ", uid=" + callingUid + ") requires "
10561                    + cpi.readPermission + " or " + cpi.writePermission;
10562        }
10563        Slog.w(TAG, msg);
10564        return msg;
10565    }
10566
10567    /**
10568     * Returns if the ContentProvider has granted a uri to callingUid
10569     */
10570    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10571        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10572        if (perms != null) {
10573            for (int i=perms.size()-1; i>=0; i--) {
10574                GrantUri grantUri = perms.keyAt(i);
10575                if (grantUri.sourceUserId == userId || !checkUser) {
10576                    if (matchesProvider(grantUri.uri, cpi)) {
10577                        return true;
10578                    }
10579                }
10580            }
10581        }
10582        return false;
10583    }
10584
10585    /**
10586     * Returns true if the uri authority is one of the authorities specified in the provider.
10587     */
10588    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10589        String uriAuth = uri.getAuthority();
10590        String cpiAuth = cpi.authority;
10591        if (cpiAuth.indexOf(';') == -1) {
10592            return cpiAuth.equals(uriAuth);
10593        }
10594        String[] cpiAuths = cpiAuth.split(";");
10595        int length = cpiAuths.length;
10596        for (int i = 0; i < length; i++) {
10597            if (cpiAuths[i].equals(uriAuth)) return true;
10598        }
10599        return false;
10600    }
10601
10602    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10603            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10604        if (r != null) {
10605            for (int i=0; i<r.conProviders.size(); i++) {
10606                ContentProviderConnection conn = r.conProviders.get(i);
10607                if (conn.provider == cpr) {
10608                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10609                            "Adding provider requested by "
10610                            + r.processName + " from process "
10611                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10612                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10613                    if (stable) {
10614                        conn.stableCount++;
10615                        conn.numStableIncs++;
10616                    } else {
10617                        conn.unstableCount++;
10618                        conn.numUnstableIncs++;
10619                    }
10620                    return conn;
10621                }
10622            }
10623            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10624            if (stable) {
10625                conn.stableCount = 1;
10626                conn.numStableIncs = 1;
10627            } else {
10628                conn.unstableCount = 1;
10629                conn.numUnstableIncs = 1;
10630            }
10631            cpr.connections.add(conn);
10632            r.conProviders.add(conn);
10633            startAssociationLocked(r.uid, r.processName, r.curProcState,
10634                    cpr.uid, cpr.name, cpr.info.processName);
10635            return conn;
10636        }
10637        cpr.addExternalProcessHandleLocked(externalProcessToken);
10638        return null;
10639    }
10640
10641    boolean decProviderCountLocked(ContentProviderConnection conn,
10642            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10643        if (conn != null) {
10644            cpr = conn.provider;
10645            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10646                    "Removing provider requested by "
10647                    + conn.client.processName + " from process "
10648                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10649                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10650            if (stable) {
10651                conn.stableCount--;
10652            } else {
10653                conn.unstableCount--;
10654            }
10655            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10656                cpr.connections.remove(conn);
10657                conn.client.conProviders.remove(conn);
10658                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10659                    // The client is more important than last activity -- note the time this
10660                    // is happening, so we keep the old provider process around a bit as last
10661                    // activity to avoid thrashing it.
10662                    if (cpr.proc != null) {
10663                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10664                    }
10665                }
10666                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10667                return true;
10668            }
10669            return false;
10670        }
10671        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10672        return false;
10673    }
10674
10675    private void checkTime(long startTime, String where) {
10676        long now = SystemClock.uptimeMillis();
10677        if ((now-startTime) > 50) {
10678            // If we are taking more than 50ms, log about it.
10679            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10680        }
10681    }
10682
10683    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10684            PROC_SPACE_TERM,
10685            PROC_SPACE_TERM|PROC_PARENS,
10686            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10687    };
10688
10689    private final long[] mProcessStateStatsLongs = new long[1];
10690
10691    boolean isProcessAliveLocked(ProcessRecord proc) {
10692        if (proc.procStatFile == null) {
10693            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10694        }
10695        mProcessStateStatsLongs[0] = 0;
10696        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10697                mProcessStateStatsLongs, null)) {
10698            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10699            return false;
10700        }
10701        final long state = mProcessStateStatsLongs[0];
10702        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10703                + (char)state);
10704        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10705    }
10706
10707    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10708            String name, IBinder token, boolean stable, int userId) {
10709        ContentProviderRecord cpr;
10710        ContentProviderConnection conn = null;
10711        ProviderInfo cpi = null;
10712
10713        synchronized(this) {
10714            long startTime = SystemClock.uptimeMillis();
10715
10716            ProcessRecord r = null;
10717            if (caller != null) {
10718                r = getRecordForAppLocked(caller);
10719                if (r == null) {
10720                    throw new SecurityException(
10721                            "Unable to find app for caller " + caller
10722                          + " (pid=" + Binder.getCallingPid()
10723                          + ") when getting content provider " + name);
10724                }
10725            }
10726
10727            boolean checkCrossUser = true;
10728
10729            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10730
10731            // First check if this content provider has been published...
10732            cpr = mProviderMap.getProviderByName(name, userId);
10733            // If that didn't work, check if it exists for user 0 and then
10734            // verify that it's a singleton provider before using it.
10735            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10736                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10737                if (cpr != null) {
10738                    cpi = cpr.info;
10739                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10740                            cpi.name, cpi.flags)
10741                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10742                        userId = UserHandle.USER_SYSTEM;
10743                        checkCrossUser = false;
10744                    } else {
10745                        cpr = null;
10746                        cpi = null;
10747                    }
10748                }
10749            }
10750
10751            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10752            if (providerRunning) {
10753                cpi = cpr.info;
10754                String msg;
10755                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10756                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10757                        != null) {
10758                    throw new SecurityException(msg);
10759                }
10760                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10761
10762                if (r != null && cpr.canRunHere(r)) {
10763                    // This provider has been published or is in the process
10764                    // of being published...  but it is also allowed to run
10765                    // in the caller's process, so don't make a connection
10766                    // and just let the caller instantiate its own instance.
10767                    ContentProviderHolder holder = cpr.newHolder(null);
10768                    // don't give caller the provider object, it needs
10769                    // to make its own.
10770                    holder.provider = null;
10771                    return holder;
10772                }
10773
10774                final long origId = Binder.clearCallingIdentity();
10775
10776                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10777
10778                // In this case the provider instance already exists, so we can
10779                // return it right away.
10780                conn = incProviderCountLocked(r, cpr, token, stable);
10781                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10782                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10783                        // If this is a perceptible app accessing the provider,
10784                        // make sure to count it as being accessed and thus
10785                        // back up on the LRU list.  This is good because
10786                        // content providers are often expensive to start.
10787                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10788                        updateLruProcessLocked(cpr.proc, false, null);
10789                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10790                    }
10791                }
10792
10793                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10794                final int verifiedAdj = cpr.proc.verifiedAdj;
10795                boolean success = updateOomAdjLocked(cpr.proc);
10796                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10797                // if the process has been successfully adjusted.  So to reduce races with
10798                // it, we will check whether the process still exists.  Note that this doesn't
10799                // completely get rid of races with LMK killing the process, but should make
10800                // them much smaller.
10801                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10802                    success = false;
10803                }
10804                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10805                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10806                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10807                // NOTE: there is still a race here where a signal could be
10808                // pending on the process even though we managed to update its
10809                // adj level.  Not sure what to do about this, but at least
10810                // the race is now smaller.
10811                if (!success) {
10812                    // Uh oh...  it looks like the provider's process
10813                    // has been killed on us.  We need to wait for a new
10814                    // process to be started, and make sure its death
10815                    // doesn't kill our process.
10816                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10817                            + " is crashing; detaching " + r);
10818                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10819                    checkTime(startTime, "getContentProviderImpl: before appDied");
10820                    appDiedLocked(cpr.proc);
10821                    checkTime(startTime, "getContentProviderImpl: after appDied");
10822                    if (!lastRef) {
10823                        // This wasn't the last ref our process had on
10824                        // the provider...  we have now been killed, bail.
10825                        return null;
10826                    }
10827                    providerRunning = false;
10828                    conn = null;
10829                } else {
10830                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10831                }
10832
10833                Binder.restoreCallingIdentity(origId);
10834            }
10835
10836            if (!providerRunning) {
10837                try {
10838                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10839                    cpi = AppGlobals.getPackageManager().
10840                        resolveContentProvider(name,
10841                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10842                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10843                } catch (RemoteException ex) {
10844                }
10845                if (cpi == null) {
10846                    return null;
10847                }
10848                // If the provider is a singleton AND
10849                // (it's a call within the same user || the provider is a
10850                // privileged app)
10851                // Then allow connecting to the singleton provider
10852                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10853                        cpi.name, cpi.flags)
10854                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10855                if (singleton) {
10856                    userId = UserHandle.USER_SYSTEM;
10857                }
10858                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10859                checkTime(startTime, "getContentProviderImpl: got app info for user");
10860
10861                String msg;
10862                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10863                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10864                        != null) {
10865                    throw new SecurityException(msg);
10866                }
10867                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10868
10869                if (!mProcessesReady
10870                        && !cpi.processName.equals("system")) {
10871                    // If this content provider does not run in the system
10872                    // process, and the system is not yet ready to run other
10873                    // processes, then fail fast instead of hanging.
10874                    throw new IllegalArgumentException(
10875                            "Attempt to launch content provider before system ready");
10876                }
10877
10878                // Make sure that the user who owns this provider is running.  If not,
10879                // we don't want to allow it to run.
10880                if (!mUserController.isUserRunningLocked(userId, 0)) {
10881                    Slog.w(TAG, "Unable to launch app "
10882                            + cpi.applicationInfo.packageName + "/"
10883                            + cpi.applicationInfo.uid + " for provider "
10884                            + name + ": user " + userId + " is stopped");
10885                    return null;
10886                }
10887
10888                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10889                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10890                cpr = mProviderMap.getProviderByClass(comp, userId);
10891                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10892                final boolean firstClass = cpr == null;
10893                if (firstClass) {
10894                    final long ident = Binder.clearCallingIdentity();
10895
10896                    // If permissions need a review before any of the app components can run,
10897                    // we return no provider and launch a review activity if the calling app
10898                    // is in the foreground.
10899                    if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10900                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10901                            return null;
10902                        }
10903                    }
10904
10905                    try {
10906                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10907                        ApplicationInfo ai =
10908                            AppGlobals.getPackageManager().
10909                                getApplicationInfo(
10910                                        cpi.applicationInfo.packageName,
10911                                        STOCK_PM_FLAGS, userId);
10912                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10913                        if (ai == null) {
10914                            Slog.w(TAG, "No package info for content provider "
10915                                    + cpi.name);
10916                            return null;
10917                        }
10918                        ai = getAppInfoForUser(ai, userId);
10919                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10920                    } catch (RemoteException ex) {
10921                        // pm is in same process, this will never happen.
10922                    } finally {
10923                        Binder.restoreCallingIdentity(ident);
10924                    }
10925                }
10926
10927                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10928
10929                if (r != null && cpr.canRunHere(r)) {
10930                    // If this is a multiprocess provider, then just return its
10931                    // info and allow the caller to instantiate it.  Only do
10932                    // this if the provider is the same user as the caller's
10933                    // process, or can run as root (so can be in any process).
10934                    return cpr.newHolder(null);
10935                }
10936
10937                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10938                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10939                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10940
10941                // This is single process, and our app is now connecting to it.
10942                // See if we are already in the process of launching this
10943                // provider.
10944                final int N = mLaunchingProviders.size();
10945                int i;
10946                for (i = 0; i < N; i++) {
10947                    if (mLaunchingProviders.get(i) == cpr) {
10948                        break;
10949                    }
10950                }
10951
10952                // If the provider is not already being launched, then get it
10953                // started.
10954                if (i >= N) {
10955                    final long origId = Binder.clearCallingIdentity();
10956
10957                    try {
10958                        // Content provider is now in use, its package can't be stopped.
10959                        try {
10960                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10961                            AppGlobals.getPackageManager().setPackageStoppedState(
10962                                    cpr.appInfo.packageName, false, userId);
10963                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10964                        } catch (RemoteException e) {
10965                        } catch (IllegalArgumentException e) {
10966                            Slog.w(TAG, "Failed trying to unstop package "
10967                                    + cpr.appInfo.packageName + ": " + e);
10968                        }
10969
10970                        // Use existing process if already started
10971                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10972                        ProcessRecord proc = getProcessRecordLocked(
10973                                cpi.processName, cpr.appInfo.uid, false);
10974                        if (proc != null && proc.thread != null && !proc.killed) {
10975                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10976                                    "Installing in existing process " + proc);
10977                            if (!proc.pubProviders.containsKey(cpi.name)) {
10978                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10979                                proc.pubProviders.put(cpi.name, cpr);
10980                                try {
10981                                    proc.thread.scheduleInstallProvider(cpi);
10982                                } catch (RemoteException e) {
10983                                }
10984                            }
10985                        } else {
10986                            checkTime(startTime, "getContentProviderImpl: before start process");
10987                            proc = startProcessLocked(cpi.processName,
10988                                    cpr.appInfo, false, 0, "content provider",
10989                                    new ComponentName(cpi.applicationInfo.packageName,
10990                                            cpi.name), false, false, false);
10991                            checkTime(startTime, "getContentProviderImpl: after start process");
10992                            if (proc == null) {
10993                                Slog.w(TAG, "Unable to launch app "
10994                                        + cpi.applicationInfo.packageName + "/"
10995                                        + cpi.applicationInfo.uid + " for provider "
10996                                        + name + ": process is bad");
10997                                return null;
10998                            }
10999                        }
11000                        cpr.launchingApp = proc;
11001                        mLaunchingProviders.add(cpr);
11002                    } finally {
11003                        Binder.restoreCallingIdentity(origId);
11004                    }
11005                }
11006
11007                checkTime(startTime, "getContentProviderImpl: updating data structures");
11008
11009                // Make sure the provider is published (the same provider class
11010                // may be published under multiple names).
11011                if (firstClass) {
11012                    mProviderMap.putProviderByClass(comp, cpr);
11013                }
11014
11015                mProviderMap.putProviderByName(name, cpr);
11016                conn = incProviderCountLocked(r, cpr, token, stable);
11017                if (conn != null) {
11018                    conn.waiting = true;
11019                }
11020            }
11021            checkTime(startTime, "getContentProviderImpl: done!");
11022        }
11023
11024        // Wait for the provider to be published...
11025        synchronized (cpr) {
11026            while (cpr.provider == null) {
11027                if (cpr.launchingApp == null) {
11028                    Slog.w(TAG, "Unable to launch app "
11029                            + cpi.applicationInfo.packageName + "/"
11030                            + cpi.applicationInfo.uid + " for provider "
11031                            + name + ": launching app became null");
11032                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11033                            UserHandle.getUserId(cpi.applicationInfo.uid),
11034                            cpi.applicationInfo.packageName,
11035                            cpi.applicationInfo.uid, name);
11036                    return null;
11037                }
11038                try {
11039                    if (DEBUG_MU) Slog.v(TAG_MU,
11040                            "Waiting to start provider " + cpr
11041                            + " launchingApp=" + cpr.launchingApp);
11042                    if (conn != null) {
11043                        conn.waiting = true;
11044                    }
11045                    cpr.wait();
11046                } catch (InterruptedException ex) {
11047                } finally {
11048                    if (conn != null) {
11049                        conn.waiting = false;
11050                    }
11051                }
11052            }
11053        }
11054        return cpr != null ? cpr.newHolder(conn) : null;
11055    }
11056
11057    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11058            ProcessRecord r, final int userId) {
11059        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11060                cpi.packageName, userId)) {
11061
11062            final boolean callerForeground = r == null || r.setSchedGroup
11063                    != ProcessList.SCHED_GROUP_BACKGROUND;
11064
11065            // Show a permission review UI only for starting from a foreground app
11066            if (!callerForeground) {
11067                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11068                        + cpi.packageName + " requires a permissions review");
11069                return false;
11070            }
11071
11072            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11073            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11074                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11075            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11076
11077            if (DEBUG_PERMISSIONS_REVIEW) {
11078                Slog.i(TAG, "u" + userId + " Launching permission review "
11079                        + "for package " + cpi.packageName);
11080            }
11081
11082            final UserHandle userHandle = new UserHandle(userId);
11083            mHandler.post(new Runnable() {
11084                @Override
11085                public void run() {
11086                    mContext.startActivityAsUser(intent, userHandle);
11087                }
11088            });
11089
11090            return false;
11091        }
11092
11093        return true;
11094    }
11095
11096    PackageManagerInternal getPackageManagerInternalLocked() {
11097        if (mPackageManagerInt == null) {
11098            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11099        }
11100        return mPackageManagerInt;
11101    }
11102
11103    @Override
11104    public final ContentProviderHolder getContentProvider(
11105            IApplicationThread caller, String name, int userId, boolean stable) {
11106        enforceNotIsolatedCaller("getContentProvider");
11107        if (caller == null) {
11108            String msg = "null IApplicationThread when getting content provider "
11109                    + name;
11110            Slog.w(TAG, msg);
11111            throw new SecurityException(msg);
11112        }
11113        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11114        // with cross-user grant.
11115        return getContentProviderImpl(caller, name, null, stable, userId);
11116    }
11117
11118    public ContentProviderHolder getContentProviderExternal(
11119            String name, int userId, IBinder token) {
11120        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11121            "Do not have permission in call getContentProviderExternal()");
11122        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11123                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11124        return getContentProviderExternalUnchecked(name, token, userId);
11125    }
11126
11127    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11128            IBinder token, int userId) {
11129        return getContentProviderImpl(null, name, token, true, userId);
11130    }
11131
11132    /**
11133     * Drop a content provider from a ProcessRecord's bookkeeping
11134     */
11135    public void removeContentProvider(IBinder connection, boolean stable) {
11136        enforceNotIsolatedCaller("removeContentProvider");
11137        long ident = Binder.clearCallingIdentity();
11138        try {
11139            synchronized (this) {
11140                ContentProviderConnection conn;
11141                try {
11142                    conn = (ContentProviderConnection)connection;
11143                } catch (ClassCastException e) {
11144                    String msg ="removeContentProvider: " + connection
11145                            + " not a ContentProviderConnection";
11146                    Slog.w(TAG, msg);
11147                    throw new IllegalArgumentException(msg);
11148                }
11149                if (conn == null) {
11150                    throw new NullPointerException("connection is null");
11151                }
11152                if (decProviderCountLocked(conn, null, null, stable)) {
11153                    updateOomAdjLocked();
11154                }
11155            }
11156        } finally {
11157            Binder.restoreCallingIdentity(ident);
11158        }
11159    }
11160
11161    public void removeContentProviderExternal(String name, IBinder token) {
11162        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11163            "Do not have permission in call removeContentProviderExternal()");
11164        int userId = UserHandle.getCallingUserId();
11165        long ident = Binder.clearCallingIdentity();
11166        try {
11167            removeContentProviderExternalUnchecked(name, token, userId);
11168        } finally {
11169            Binder.restoreCallingIdentity(ident);
11170        }
11171    }
11172
11173    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11174        synchronized (this) {
11175            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11176            if(cpr == null) {
11177                //remove from mProvidersByClass
11178                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11179                return;
11180            }
11181
11182            //update content provider record entry info
11183            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11184            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11185            if (localCpr.hasExternalProcessHandles()) {
11186                if (localCpr.removeExternalProcessHandleLocked(token)) {
11187                    updateOomAdjLocked();
11188                } else {
11189                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11190                            + " with no external reference for token: "
11191                            + token + ".");
11192                }
11193            } else {
11194                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11195                        + " with no external references.");
11196            }
11197        }
11198    }
11199
11200    public final void publishContentProviders(IApplicationThread caller,
11201            List<ContentProviderHolder> providers) {
11202        if (providers == null) {
11203            return;
11204        }
11205
11206        enforceNotIsolatedCaller("publishContentProviders");
11207        synchronized (this) {
11208            final ProcessRecord r = getRecordForAppLocked(caller);
11209            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11210            if (r == null) {
11211                throw new SecurityException(
11212                        "Unable to find app for caller " + caller
11213                      + " (pid=" + Binder.getCallingPid()
11214                      + ") when publishing content providers");
11215            }
11216
11217            final long origId = Binder.clearCallingIdentity();
11218
11219            final int N = providers.size();
11220            for (int i = 0; i < N; i++) {
11221                ContentProviderHolder src = providers.get(i);
11222                if (src == null || src.info == null || src.provider == null) {
11223                    continue;
11224                }
11225                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11226                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11227                if (dst != null) {
11228                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11229                    mProviderMap.putProviderByClass(comp, dst);
11230                    String names[] = dst.info.authority.split(";");
11231                    for (int j = 0; j < names.length; j++) {
11232                        mProviderMap.putProviderByName(names[j], dst);
11233                    }
11234
11235                    int launchingCount = mLaunchingProviders.size();
11236                    int j;
11237                    boolean wasInLaunchingProviders = false;
11238                    for (j = 0; j < launchingCount; j++) {
11239                        if (mLaunchingProviders.get(j) == dst) {
11240                            mLaunchingProviders.remove(j);
11241                            wasInLaunchingProviders = true;
11242                            j--;
11243                            launchingCount--;
11244                        }
11245                    }
11246                    if (wasInLaunchingProviders) {
11247                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11248                    }
11249                    synchronized (dst) {
11250                        dst.provider = src.provider;
11251                        dst.proc = r;
11252                        dst.notifyAll();
11253                    }
11254                    updateOomAdjLocked(r);
11255                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11256                            src.info.authority);
11257                }
11258            }
11259
11260            Binder.restoreCallingIdentity(origId);
11261        }
11262    }
11263
11264    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11265        ContentProviderConnection conn;
11266        try {
11267            conn = (ContentProviderConnection)connection;
11268        } catch (ClassCastException e) {
11269            String msg ="refContentProvider: " + connection
11270                    + " not a ContentProviderConnection";
11271            Slog.w(TAG, msg);
11272            throw new IllegalArgumentException(msg);
11273        }
11274        if (conn == null) {
11275            throw new NullPointerException("connection is null");
11276        }
11277
11278        synchronized (this) {
11279            if (stable > 0) {
11280                conn.numStableIncs += stable;
11281            }
11282            stable = conn.stableCount + stable;
11283            if (stable < 0) {
11284                throw new IllegalStateException("stableCount < 0: " + stable);
11285            }
11286
11287            if (unstable > 0) {
11288                conn.numUnstableIncs += unstable;
11289            }
11290            unstable = conn.unstableCount + unstable;
11291            if (unstable < 0) {
11292                throw new IllegalStateException("unstableCount < 0: " + unstable);
11293            }
11294
11295            if ((stable+unstable) <= 0) {
11296                throw new IllegalStateException("ref counts can't go to zero here: stable="
11297                        + stable + " unstable=" + unstable);
11298            }
11299            conn.stableCount = stable;
11300            conn.unstableCount = unstable;
11301            return !conn.dead;
11302        }
11303    }
11304
11305    public void unstableProviderDied(IBinder connection) {
11306        ContentProviderConnection conn;
11307        try {
11308            conn = (ContentProviderConnection)connection;
11309        } catch (ClassCastException e) {
11310            String msg ="refContentProvider: " + connection
11311                    + " not a ContentProviderConnection";
11312            Slog.w(TAG, msg);
11313            throw new IllegalArgumentException(msg);
11314        }
11315        if (conn == null) {
11316            throw new NullPointerException("connection is null");
11317        }
11318
11319        // Safely retrieve the content provider associated with the connection.
11320        IContentProvider provider;
11321        synchronized (this) {
11322            provider = conn.provider.provider;
11323        }
11324
11325        if (provider == null) {
11326            // Um, yeah, we're way ahead of you.
11327            return;
11328        }
11329
11330        // Make sure the caller is being honest with us.
11331        if (provider.asBinder().pingBinder()) {
11332            // Er, no, still looks good to us.
11333            synchronized (this) {
11334                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11335                        + " says " + conn + " died, but we don't agree");
11336                return;
11337            }
11338        }
11339
11340        // Well look at that!  It's dead!
11341        synchronized (this) {
11342            if (conn.provider.provider != provider) {
11343                // But something changed...  good enough.
11344                return;
11345            }
11346
11347            ProcessRecord proc = conn.provider.proc;
11348            if (proc == null || proc.thread == null) {
11349                // Seems like the process is already cleaned up.
11350                return;
11351            }
11352
11353            // As far as we're concerned, this is just like receiving a
11354            // death notification...  just a bit prematurely.
11355            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11356                    + ") early provider death");
11357            final long ident = Binder.clearCallingIdentity();
11358            try {
11359                appDiedLocked(proc);
11360            } finally {
11361                Binder.restoreCallingIdentity(ident);
11362            }
11363        }
11364    }
11365
11366    @Override
11367    public void appNotRespondingViaProvider(IBinder connection) {
11368        enforceCallingPermission(
11369                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11370
11371        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11372        if (conn == null) {
11373            Slog.w(TAG, "ContentProviderConnection is null");
11374            return;
11375        }
11376
11377        final ProcessRecord host = conn.provider.proc;
11378        if (host == null) {
11379            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11380            return;
11381        }
11382
11383        mHandler.post(new Runnable() {
11384            @Override
11385            public void run() {
11386                mAppErrors.appNotResponding(host, null, null, false,
11387                        "ContentProvider not responding");
11388            }
11389        });
11390    }
11391
11392    public final void installSystemProviders() {
11393        List<ProviderInfo> providers;
11394        synchronized (this) {
11395            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11396            providers = generateApplicationProvidersLocked(app);
11397            if (providers != null) {
11398                for (int i=providers.size()-1; i>=0; i--) {
11399                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11400                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11401                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11402                                + ": not system .apk");
11403                        providers.remove(i);
11404                    }
11405                }
11406            }
11407        }
11408        if (providers != null) {
11409            mSystemThread.installSystemProviders(providers);
11410        }
11411
11412        mCoreSettingsObserver = new CoreSettingsObserver(this);
11413        mFontScaleSettingObserver = new FontScaleSettingObserver();
11414
11415        //mUsageStatsService.monitorPackages();
11416    }
11417
11418    private void startPersistentApps(int matchFlags) {
11419        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11420
11421        synchronized (this) {
11422            try {
11423                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11424                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11425                for (ApplicationInfo app : apps) {
11426                    if (!"android".equals(app.packageName)) {
11427                        addAppLocked(app, false, null /* ABI override */);
11428                    }
11429                }
11430            } catch (RemoteException ex) {
11431            }
11432        }
11433    }
11434
11435    /**
11436     * When a user is unlocked, we need to install encryption-unaware providers
11437     * belonging to any running apps.
11438     */
11439    private void installEncryptionUnawareProviders(int userId) {
11440        // We're only interested in providers that are encryption unaware, and
11441        // we don't care about uninstalled apps, since there's no way they're
11442        // running at this point.
11443        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11444
11445        synchronized (this) {
11446            final int NP = mProcessNames.getMap().size();
11447            for (int ip = 0; ip < NP; ip++) {
11448                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11449                final int NA = apps.size();
11450                for (int ia = 0; ia < NA; ia++) {
11451                    final ProcessRecord app = apps.valueAt(ia);
11452                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11453
11454                    final int NG = app.pkgList.size();
11455                    for (int ig = 0; ig < NG; ig++) {
11456                        try {
11457                            final String pkgName = app.pkgList.keyAt(ig);
11458                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11459                                    .getPackageInfo(pkgName, matchFlags, userId);
11460                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11461                                for (ProviderInfo pi : pkgInfo.providers) {
11462                                    // TODO: keep in sync with generateApplicationProvidersLocked
11463                                    final boolean processMatch = Objects.equals(pi.processName,
11464                                            app.processName) || pi.multiprocess;
11465                                    final boolean userMatch = isSingleton(pi.processName,
11466                                            pi.applicationInfo, pi.name, pi.flags)
11467                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11468                                    if (processMatch && userMatch) {
11469                                        Log.v(TAG, "Installing " + pi);
11470                                        app.thread.scheduleInstallProvider(pi);
11471                                    } else {
11472                                        Log.v(TAG, "Skipping " + pi);
11473                                    }
11474                                }
11475                            }
11476                        } catch (RemoteException ignored) {
11477                        }
11478                    }
11479                }
11480            }
11481        }
11482    }
11483
11484    /**
11485     * Allows apps to retrieve the MIME type of a URI.
11486     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11487     * users, then it does not need permission to access the ContentProvider.
11488     * Either, it needs cross-user uri grants.
11489     *
11490     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11491     *
11492     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11493     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11494     */
11495    public String getProviderMimeType(Uri uri, int userId) {
11496        enforceNotIsolatedCaller("getProviderMimeType");
11497        final String name = uri.getAuthority();
11498        int callingUid = Binder.getCallingUid();
11499        int callingPid = Binder.getCallingPid();
11500        long ident = 0;
11501        boolean clearedIdentity = false;
11502        synchronized (this) {
11503            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11504        }
11505        if (canClearIdentity(callingPid, callingUid, userId)) {
11506            clearedIdentity = true;
11507            ident = Binder.clearCallingIdentity();
11508        }
11509        ContentProviderHolder holder = null;
11510        try {
11511            holder = getContentProviderExternalUnchecked(name, null, userId);
11512            if (holder != null) {
11513                return holder.provider.getType(uri);
11514            }
11515        } catch (RemoteException e) {
11516            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11517            return null;
11518        } catch (Exception e) {
11519            Log.w(TAG, "Exception while determining type of " + uri, e);
11520            return null;
11521        } finally {
11522            // We need to clear the identity to call removeContentProviderExternalUnchecked
11523            if (!clearedIdentity) {
11524                ident = Binder.clearCallingIdentity();
11525            }
11526            try {
11527                if (holder != null) {
11528                    removeContentProviderExternalUnchecked(name, null, userId);
11529                }
11530            } finally {
11531                Binder.restoreCallingIdentity(ident);
11532            }
11533        }
11534
11535        return null;
11536    }
11537
11538    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11539        if (UserHandle.getUserId(callingUid) == userId) {
11540            return true;
11541        }
11542        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11543                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11544                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11545                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11546                return true;
11547        }
11548        return false;
11549    }
11550
11551    // =========================================================
11552    // GLOBAL MANAGEMENT
11553    // =========================================================
11554
11555    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11556            boolean isolated, int isolatedUid) {
11557        String proc = customProcess != null ? customProcess : info.processName;
11558        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11559        final int userId = UserHandle.getUserId(info.uid);
11560        int uid = info.uid;
11561        if (isolated) {
11562            if (isolatedUid == 0) {
11563                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11564                while (true) {
11565                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11566                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11567                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11568                    }
11569                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11570                    mNextIsolatedProcessUid++;
11571                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11572                        // No process for this uid, use it.
11573                        break;
11574                    }
11575                    stepsLeft--;
11576                    if (stepsLeft <= 0) {
11577                        return null;
11578                    }
11579                }
11580            } else {
11581                // Special case for startIsolatedProcess (internal only), where
11582                // the uid of the isolated process is specified by the caller.
11583                uid = isolatedUid;
11584            }
11585
11586            // Register the isolated UID with this application so BatteryStats knows to
11587            // attribute resource usage to the application.
11588            //
11589            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11590            // about the process state of the isolated UID *before* it is registered with the
11591            // owning application.
11592            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11593        }
11594        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11595        if (!mBooted && !mBooting
11596                && userId == UserHandle.USER_SYSTEM
11597                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11598            r.persistent = true;
11599            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11600        }
11601        addProcessNameLocked(r);
11602        return r;
11603    }
11604
11605    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11606            String abiOverride) {
11607        ProcessRecord app;
11608        if (!isolated) {
11609            app = getProcessRecordLocked(info.processName, info.uid, true);
11610        } else {
11611            app = null;
11612        }
11613
11614        if (app == null) {
11615            app = newProcessRecordLocked(info, null, isolated, 0);
11616            updateLruProcessLocked(app, false, null);
11617            updateOomAdjLocked();
11618        }
11619
11620        // This package really, really can not be stopped.
11621        try {
11622            AppGlobals.getPackageManager().setPackageStoppedState(
11623                    info.packageName, false, UserHandle.getUserId(app.uid));
11624        } catch (RemoteException e) {
11625        } catch (IllegalArgumentException e) {
11626            Slog.w(TAG, "Failed trying to unstop package "
11627                    + info.packageName + ": " + e);
11628        }
11629
11630        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11631            app.persistent = true;
11632            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11633        }
11634        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11635            mPersistentStartingProcesses.add(app);
11636            startProcessLocked(app, "added application", app.processName, abiOverride,
11637                    null /* entryPoint */, null /* entryPointArgs */);
11638        }
11639
11640        return app;
11641    }
11642
11643    public void unhandledBack() {
11644        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11645                "unhandledBack()");
11646
11647        synchronized(this) {
11648            final long origId = Binder.clearCallingIdentity();
11649            try {
11650                getFocusedStack().unhandledBackLocked();
11651            } finally {
11652                Binder.restoreCallingIdentity(origId);
11653            }
11654        }
11655    }
11656
11657    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11658        enforceNotIsolatedCaller("openContentUri");
11659        final int userId = UserHandle.getCallingUserId();
11660        String name = uri.getAuthority();
11661        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11662        ParcelFileDescriptor pfd = null;
11663        if (cph != null) {
11664            // We record the binder invoker's uid in thread-local storage before
11665            // going to the content provider to open the file.  Later, in the code
11666            // that handles all permissions checks, we look for this uid and use
11667            // that rather than the Activity Manager's own uid.  The effect is that
11668            // we do the check against the caller's permissions even though it looks
11669            // to the content provider like the Activity Manager itself is making
11670            // the request.
11671            Binder token = new Binder();
11672            sCallerIdentity.set(new Identity(
11673                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11674            try {
11675                pfd = cph.provider.openFile(null, uri, "r", null, token);
11676            } catch (FileNotFoundException e) {
11677                // do nothing; pfd will be returned null
11678            } finally {
11679                // Ensure that whatever happens, we clean up the identity state
11680                sCallerIdentity.remove();
11681                // Ensure we're done with the provider.
11682                removeContentProviderExternalUnchecked(name, null, userId);
11683            }
11684        } else {
11685            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11686        }
11687        return pfd;
11688    }
11689
11690    // Actually is sleeping or shutting down or whatever else in the future
11691    // is an inactive state.
11692    boolean isSleepingOrShuttingDownLocked() {
11693        return isSleepingLocked() || mShuttingDown;
11694    }
11695
11696    boolean isShuttingDownLocked() {
11697        return mShuttingDown;
11698    }
11699
11700    boolean isSleepingLocked() {
11701        return mSleeping;
11702    }
11703
11704    void onWakefulnessChanged(int wakefulness) {
11705        synchronized(this) {
11706            mWakefulness = wakefulness;
11707            updateSleepIfNeededLocked();
11708        }
11709    }
11710
11711    void finishRunningVoiceLocked() {
11712        if (mRunningVoice != null) {
11713            mRunningVoice = null;
11714            mVoiceWakeLock.release();
11715            updateSleepIfNeededLocked();
11716        }
11717    }
11718
11719    void startTimeTrackingFocusedActivityLocked() {
11720        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11721            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11722        }
11723    }
11724
11725    void updateSleepIfNeededLocked() {
11726        if (mSleeping && !shouldSleepLocked()) {
11727            mSleeping = false;
11728            startTimeTrackingFocusedActivityLocked();
11729            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11730            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11731            sendNotifyVrManagerOfSleepState(false);
11732            updateOomAdjLocked();
11733        } else if (!mSleeping && shouldSleepLocked()) {
11734            mSleeping = true;
11735            if (mCurAppTimeTracker != null) {
11736                mCurAppTimeTracker.stop();
11737            }
11738            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11739            mStackSupervisor.goingToSleepLocked();
11740            sendNotifyVrManagerOfSleepState(true);
11741            updateOomAdjLocked();
11742
11743            // Initialize the wake times of all processes.
11744            checkExcessivePowerUsageLocked(false);
11745            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11746            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11747            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11748        }
11749    }
11750
11751    private boolean shouldSleepLocked() {
11752        // Resume applications while running a voice interactor.
11753        if (mRunningVoice != null) {
11754            return false;
11755        }
11756
11757        // TODO: Transform the lock screen state into a sleep token instead.
11758        switch (mWakefulness) {
11759            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11760            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11761            case PowerManagerInternal.WAKEFULNESS_DOZING:
11762                // Pause applications whenever the lock screen is shown or any sleep
11763                // tokens have been acquired.
11764                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11765            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11766            default:
11767                // If we're asleep then pause applications unconditionally.
11768                return true;
11769        }
11770    }
11771
11772    /** Pokes the task persister. */
11773    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11774        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11775    }
11776
11777    /** Notifies all listeners when the task stack has changed. */
11778    void notifyTaskStackChangedLocked() {
11779        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11780        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11781        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11782        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11783    }
11784
11785    /** Notifies all listeners when an Activity is pinned. */
11786    void notifyActivityPinnedLocked() {
11787        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11788        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11789    }
11790
11791    /**
11792     * Notifies all listeners when an attempt was made to start an an activity that is already
11793     * running in the pinned stack and the activity was not actually started, but the task is
11794     * either brought to the front or a new Intent is delivered to it.
11795     */
11796    void notifyPinnedActivityRestartAttemptLocked() {
11797        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11798        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11799    }
11800
11801    /** Notifies all listeners when the pinned stack animation ends. */
11802    @Override
11803    public void notifyPinnedStackAnimationEnded() {
11804        synchronized (this) {
11805            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11806            mHandler.obtainMessage(
11807                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11808        }
11809    }
11810
11811    @Override
11812    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11813        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11814    }
11815
11816    @Override
11817    public boolean shutdown(int timeout) {
11818        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11819                != PackageManager.PERMISSION_GRANTED) {
11820            throw new SecurityException("Requires permission "
11821                    + android.Manifest.permission.SHUTDOWN);
11822        }
11823
11824        boolean timedout = false;
11825
11826        synchronized(this) {
11827            mShuttingDown = true;
11828            updateEventDispatchingLocked();
11829            timedout = mStackSupervisor.shutdownLocked(timeout);
11830        }
11831
11832        mAppOpsService.shutdown();
11833        if (mUsageStatsService != null) {
11834            mUsageStatsService.prepareShutdown();
11835        }
11836        mBatteryStatsService.shutdown();
11837        synchronized (this) {
11838            mProcessStats.shutdownLocked();
11839            notifyTaskPersisterLocked(null, true);
11840        }
11841
11842        return timedout;
11843    }
11844
11845    public final void activitySlept(IBinder token) {
11846        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11847
11848        final long origId = Binder.clearCallingIdentity();
11849
11850        synchronized (this) {
11851            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11852            if (r != null) {
11853                mStackSupervisor.activitySleptLocked(r);
11854            }
11855        }
11856
11857        Binder.restoreCallingIdentity(origId);
11858    }
11859
11860    private String lockScreenShownToString() {
11861        switch (mLockScreenShown) {
11862            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11863            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11864            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11865            default: return "Unknown=" + mLockScreenShown;
11866        }
11867    }
11868
11869    void logLockScreen(String msg) {
11870        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11871                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11872                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11873                + " mSleeping=" + mSleeping);
11874    }
11875
11876    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11877        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11878        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11879        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11880            boolean wasRunningVoice = mRunningVoice != null;
11881            mRunningVoice = session;
11882            if (!wasRunningVoice) {
11883                mVoiceWakeLock.acquire();
11884                updateSleepIfNeededLocked();
11885            }
11886        }
11887    }
11888
11889    private void updateEventDispatchingLocked() {
11890        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11891    }
11892
11893    public void setLockScreenShown(boolean showing, boolean occluded) {
11894        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11895                != PackageManager.PERMISSION_GRANTED) {
11896            throw new SecurityException("Requires permission "
11897                    + android.Manifest.permission.DEVICE_POWER);
11898        }
11899
11900        synchronized(this) {
11901            long ident = Binder.clearCallingIdentity();
11902            try {
11903                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11904                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11905                if (showing && occluded) {
11906                    // The lock screen is currently showing, but is occluded by a window that can
11907                    // show on top of the lock screen. In this can we want to dismiss the docked
11908                    // stack since it will be complicated/risky to try to put the activity on top
11909                    // of the lock screen in the right fullscreen configuration.
11910                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11911                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11912                }
11913
11914                updateSleepIfNeededLocked();
11915            } finally {
11916                Binder.restoreCallingIdentity(ident);
11917            }
11918        }
11919    }
11920
11921    @Override
11922    public void notifyLockedProfile(@UserIdInt int userId) {
11923        try {
11924            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11925                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11926            }
11927        } catch (RemoteException ex) {
11928            throw new SecurityException("Fail to check is caller a privileged app", ex);
11929        }
11930
11931        synchronized (this) {
11932            if (mStackSupervisor.isUserLockedProfile(userId)) {
11933                final long ident = Binder.clearCallingIdentity();
11934                try {
11935                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11936
11937                    // Drop locked freeform tasks out into the fullscreen stack.
11938                    // TODO: Redact the tasks in place. It's much better to keep them on the screen
11939                    //       where they were before, but in an obscured state.
11940                    mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11941
11942                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11943                        // If there is no device lock, we will show the profile's credential page.
11944                        mActivityStarter.showConfirmDeviceCredential(userId);
11945                    } else {
11946                        // Showing launcher to avoid user entering credential twice.
11947                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11948                    }
11949                } finally {
11950                    Binder.restoreCallingIdentity(ident);
11951                }
11952            }
11953        }
11954    }
11955
11956    @Override
11957    public void startConfirmDeviceCredentialIntent(Intent intent) {
11958        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11959        synchronized (this) {
11960            final long ident = Binder.clearCallingIdentity();
11961            try {
11962                mActivityStarter.startConfirmCredentialIntent(intent);
11963            } finally {
11964                Binder.restoreCallingIdentity(ident);
11965            }
11966        }
11967    }
11968
11969    @Override
11970    public void stopAppSwitches() {
11971        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11972                != PackageManager.PERMISSION_GRANTED) {
11973            throw new SecurityException("viewquires permission "
11974                    + android.Manifest.permission.STOP_APP_SWITCHES);
11975        }
11976
11977        synchronized(this) {
11978            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11979                    + APP_SWITCH_DELAY_TIME;
11980            mDidAppSwitch = false;
11981            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11982            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11983            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11984        }
11985    }
11986
11987    public void resumeAppSwitches() {
11988        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11989                != PackageManager.PERMISSION_GRANTED) {
11990            throw new SecurityException("Requires permission "
11991                    + android.Manifest.permission.STOP_APP_SWITCHES);
11992        }
11993
11994        synchronized(this) {
11995            // Note that we don't execute any pending app switches... we will
11996            // let those wait until either the timeout, or the next start
11997            // activity request.
11998            mAppSwitchesAllowedTime = 0;
11999        }
12000    }
12001
12002    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12003            int callingPid, int callingUid, String name) {
12004        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12005            return true;
12006        }
12007
12008        int perm = checkComponentPermission(
12009                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12010                sourceUid, -1, true);
12011        if (perm == PackageManager.PERMISSION_GRANTED) {
12012            return true;
12013        }
12014
12015        // If the actual IPC caller is different from the logical source, then
12016        // also see if they are allowed to control app switches.
12017        if (callingUid != -1 && callingUid != sourceUid) {
12018            perm = checkComponentPermission(
12019                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12020                    callingUid, -1, true);
12021            if (perm == PackageManager.PERMISSION_GRANTED) {
12022                return true;
12023            }
12024        }
12025
12026        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12027        return false;
12028    }
12029
12030    public void setDebugApp(String packageName, boolean waitForDebugger,
12031            boolean persistent) {
12032        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12033                "setDebugApp()");
12034
12035        long ident = Binder.clearCallingIdentity();
12036        try {
12037            // Note that this is not really thread safe if there are multiple
12038            // callers into it at the same time, but that's not a situation we
12039            // care about.
12040            if (persistent) {
12041                final ContentResolver resolver = mContext.getContentResolver();
12042                Settings.Global.putString(
12043                    resolver, Settings.Global.DEBUG_APP,
12044                    packageName);
12045                Settings.Global.putInt(
12046                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12047                    waitForDebugger ? 1 : 0);
12048            }
12049
12050            synchronized (this) {
12051                if (!persistent) {
12052                    mOrigDebugApp = mDebugApp;
12053                    mOrigWaitForDebugger = mWaitForDebugger;
12054                }
12055                mDebugApp = packageName;
12056                mWaitForDebugger = waitForDebugger;
12057                mDebugTransient = !persistent;
12058                if (packageName != null) {
12059                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12060                            false, UserHandle.USER_ALL, "set debug app");
12061                }
12062            }
12063        } finally {
12064            Binder.restoreCallingIdentity(ident);
12065        }
12066    }
12067
12068    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12069        synchronized (this) {
12070            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12071            if (!isDebuggable) {
12072                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12073                    throw new SecurityException("Process not debuggable: " + app.packageName);
12074                }
12075            }
12076
12077            mTrackAllocationApp = processName;
12078        }
12079    }
12080
12081    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12082        synchronized (this) {
12083            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12084            if (!isDebuggable) {
12085                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12086                    throw new SecurityException("Process not debuggable: " + app.packageName);
12087                }
12088            }
12089            mProfileApp = processName;
12090            mProfileFile = profilerInfo.profileFile;
12091            if (mProfileFd != null) {
12092                try {
12093                    mProfileFd.close();
12094                } catch (IOException e) {
12095                }
12096                mProfileFd = null;
12097            }
12098            mProfileFd = profilerInfo.profileFd;
12099            mSamplingInterval = profilerInfo.samplingInterval;
12100            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12101            mProfileType = 0;
12102        }
12103    }
12104
12105    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12106        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12107        if (!isDebuggable) {
12108            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12109                throw new SecurityException("Process not debuggable: " + app.packageName);
12110            }
12111        }
12112        mNativeDebuggingApp = processName;
12113    }
12114
12115    @Override
12116    public void setAlwaysFinish(boolean enabled) {
12117        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12118                "setAlwaysFinish()");
12119
12120        long ident = Binder.clearCallingIdentity();
12121        try {
12122            Settings.Global.putInt(
12123                    mContext.getContentResolver(),
12124                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12125
12126            synchronized (this) {
12127                mAlwaysFinishActivities = enabled;
12128            }
12129        } finally {
12130            Binder.restoreCallingIdentity(ident);
12131        }
12132    }
12133
12134    @Override
12135    public void setLenientBackgroundCheck(boolean enabled) {
12136        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12137                "setLenientBackgroundCheck()");
12138
12139        long ident = Binder.clearCallingIdentity();
12140        try {
12141            Settings.Global.putInt(
12142                    mContext.getContentResolver(),
12143                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12144
12145            synchronized (this) {
12146                mLenientBackgroundCheck = enabled;
12147            }
12148        } finally {
12149            Binder.restoreCallingIdentity(ident);
12150        }
12151    }
12152
12153    @Override
12154    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12155        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12156                "setActivityController()");
12157        synchronized (this) {
12158            mController = controller;
12159            mControllerIsAMonkey = imAMonkey;
12160            Watchdog.getInstance().setActivityController(controller);
12161        }
12162    }
12163
12164    @Override
12165    public void setUserIsMonkey(boolean userIsMonkey) {
12166        synchronized (this) {
12167            synchronized (mPidsSelfLocked) {
12168                final int callingPid = Binder.getCallingPid();
12169                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12170                if (precessRecord == null) {
12171                    throw new SecurityException("Unknown process: " + callingPid);
12172                }
12173                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12174                    throw new SecurityException("Only an instrumentation process "
12175                            + "with a UiAutomation can call setUserIsMonkey");
12176                }
12177            }
12178            mUserIsMonkey = userIsMonkey;
12179        }
12180    }
12181
12182    @Override
12183    public boolean isUserAMonkey() {
12184        synchronized (this) {
12185            // If there is a controller also implies the user is a monkey.
12186            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12187        }
12188    }
12189
12190    public void requestBugReport(int bugreportType) {
12191        String service = null;
12192        switch (bugreportType) {
12193            case ActivityManager.BUGREPORT_OPTION_FULL:
12194                service = "bugreport";
12195                break;
12196            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12197                service = "bugreportplus";
12198                break;
12199            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12200                service = "bugreportremote";
12201                break;
12202            case ActivityManager.BUGREPORT_OPTION_WEAR:
12203                service = "bugreportwear";
12204                break;
12205            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12206                service = "bugreportelefony";
12207                break;
12208        }
12209        if (service == null) {
12210            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12211                    + bugreportType);
12212        }
12213        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12214        SystemProperties.set("ctl.start", service);
12215    }
12216
12217    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12218        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12219    }
12220
12221    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12222        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12223            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12224        }
12225        return KEY_DISPATCHING_TIMEOUT;
12226    }
12227
12228    @Override
12229    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12230        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12231                != PackageManager.PERMISSION_GRANTED) {
12232            throw new SecurityException("Requires permission "
12233                    + android.Manifest.permission.FILTER_EVENTS);
12234        }
12235        ProcessRecord proc;
12236        long timeout;
12237        synchronized (this) {
12238            synchronized (mPidsSelfLocked) {
12239                proc = mPidsSelfLocked.get(pid);
12240            }
12241            timeout = getInputDispatchingTimeoutLocked(proc);
12242        }
12243
12244        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12245            return -1;
12246        }
12247
12248        return timeout;
12249    }
12250
12251    /**
12252     * Handle input dispatching timeouts.
12253     * Returns whether input dispatching should be aborted or not.
12254     */
12255    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12256            final ActivityRecord activity, final ActivityRecord parent,
12257            final boolean aboveSystem, String reason) {
12258        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12259                != PackageManager.PERMISSION_GRANTED) {
12260            throw new SecurityException("Requires permission "
12261                    + android.Manifest.permission.FILTER_EVENTS);
12262        }
12263
12264        final String annotation;
12265        if (reason == null) {
12266            annotation = "Input dispatching timed out";
12267        } else {
12268            annotation = "Input dispatching timed out (" + reason + ")";
12269        }
12270
12271        if (proc != null) {
12272            synchronized (this) {
12273                if (proc.debugging) {
12274                    return false;
12275                }
12276
12277                if (mDidDexOpt) {
12278                    // Give more time since we were dexopting.
12279                    mDidDexOpt = false;
12280                    return false;
12281                }
12282
12283                if (proc.instrumentationClass != null) {
12284                    Bundle info = new Bundle();
12285                    info.putString("shortMsg", "keyDispatchingTimedOut");
12286                    info.putString("longMsg", annotation);
12287                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12288                    return true;
12289                }
12290            }
12291            mHandler.post(new Runnable() {
12292                @Override
12293                public void run() {
12294                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12295                }
12296            });
12297        }
12298
12299        return true;
12300    }
12301
12302    @Override
12303    public Bundle getAssistContextExtras(int requestType) {
12304        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12305                null, null, true /* focused */, true /* newSessionId */,
12306                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12307        if (pae == null) {
12308            return null;
12309        }
12310        synchronized (pae) {
12311            while (!pae.haveResult) {
12312                try {
12313                    pae.wait();
12314                } catch (InterruptedException e) {
12315                }
12316            }
12317        }
12318        synchronized (this) {
12319            buildAssistBundleLocked(pae, pae.result);
12320            mPendingAssistExtras.remove(pae);
12321            mUiHandler.removeCallbacks(pae);
12322        }
12323        return pae.extras;
12324    }
12325
12326    @Override
12327    public boolean isAssistDataAllowedOnCurrentActivity() {
12328        int userId;
12329        synchronized (this) {
12330            userId = mUserController.getCurrentUserIdLocked();
12331            ActivityRecord activity = getFocusedStack().topActivity();
12332            if (activity == null) {
12333                return false;
12334            }
12335            userId = activity.userId;
12336        }
12337        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12338                Context.DEVICE_POLICY_SERVICE);
12339        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12340    }
12341
12342    @Override
12343    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12344        long ident = Binder.clearCallingIdentity();
12345        try {
12346            synchronized (this) {
12347                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12348                ActivityRecord top = getFocusedStack().topActivity();
12349                if (top != caller) {
12350                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12351                            + " is not current top " + top);
12352                    return false;
12353                }
12354                if (!top.nowVisible) {
12355                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12356                            + " is not visible");
12357                    return false;
12358                }
12359            }
12360            AssistUtils utils = new AssistUtils(mContext);
12361            return utils.showSessionForActiveService(args,
12362                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12363        } finally {
12364            Binder.restoreCallingIdentity(ident);
12365        }
12366    }
12367
12368    @Override
12369    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12370            Bundle receiverExtras,
12371            IBinder activityToken, boolean focused, boolean newSessionId) {
12372        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12373                activityToken, focused, newSessionId,
12374                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12375                != null;
12376    }
12377
12378    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12379            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12380            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12381        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12382                "enqueueAssistContext()");
12383        synchronized (this) {
12384            ActivityRecord activity = getFocusedStack().topActivity();
12385            if (activity == null) {
12386                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12387                return null;
12388            }
12389            if (activity.app == null || activity.app.thread == null) {
12390                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12391                return null;
12392            }
12393            if (focused) {
12394                if (activityToken != null) {
12395                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12396                    if (activity != caller) {
12397                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12398                                + " is not current top " + activity);
12399                        return null;
12400                    }
12401                }
12402            } else {
12403                activity = ActivityRecord.forTokenLocked(activityToken);
12404                if (activity == null) {
12405                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12406                            + " couldn't be found");
12407                    return null;
12408                }
12409            }
12410
12411            PendingAssistExtras pae;
12412            Bundle extras = new Bundle();
12413            if (args != null) {
12414                extras.putAll(args);
12415            }
12416            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12417            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12418            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12419                    userHandle);
12420            // Increment the sessionId if necessary
12421            if (newSessionId) {
12422                mViSessionId++;
12423            }
12424            try {
12425                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12426                        requestType, mViSessionId);
12427                mPendingAssistExtras.add(pae);
12428                mUiHandler.postDelayed(pae, timeout);
12429            } catch (RemoteException e) {
12430                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12431                return null;
12432            }
12433            return pae;
12434        }
12435    }
12436
12437    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12438        IResultReceiver receiver;
12439        synchronized (this) {
12440            mPendingAssistExtras.remove(pae);
12441            receiver = pae.receiver;
12442        }
12443        if (receiver != null) {
12444            // Caller wants result sent back to them.
12445            Bundle sendBundle = new Bundle();
12446            // At least return the receiver extras
12447            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12448                    pae.receiverExtras);
12449            try {
12450                pae.receiver.send(0, sendBundle);
12451            } catch (RemoteException e) {
12452            }
12453        }
12454    }
12455
12456    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12457        if (result != null) {
12458            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12459        }
12460        if (pae.hint != null) {
12461            pae.extras.putBoolean(pae.hint, true);
12462        }
12463    }
12464
12465    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12466            AssistContent content, Uri referrer) {
12467        PendingAssistExtras pae = (PendingAssistExtras)token;
12468        synchronized (pae) {
12469            pae.result = extras;
12470            pae.structure = structure;
12471            pae.content = content;
12472            if (referrer != null) {
12473                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12474            }
12475            pae.haveResult = true;
12476            pae.notifyAll();
12477            if (pae.intent == null && pae.receiver == null) {
12478                // Caller is just waiting for the result.
12479                return;
12480            }
12481        }
12482
12483        // We are now ready to launch the assist activity.
12484        IResultReceiver sendReceiver = null;
12485        Bundle sendBundle = null;
12486        synchronized (this) {
12487            buildAssistBundleLocked(pae, extras);
12488            boolean exists = mPendingAssistExtras.remove(pae);
12489            mUiHandler.removeCallbacks(pae);
12490            if (!exists) {
12491                // Timed out.
12492                return;
12493            }
12494            if ((sendReceiver=pae.receiver) != null) {
12495                // Caller wants result sent back to them.
12496                sendBundle = new Bundle();
12497                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12498                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12499                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12500                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12501                        pae.receiverExtras);
12502            }
12503        }
12504        if (sendReceiver != null) {
12505            try {
12506                sendReceiver.send(0, sendBundle);
12507            } catch (RemoteException e) {
12508            }
12509            return;
12510        }
12511
12512        long ident = Binder.clearCallingIdentity();
12513        try {
12514            pae.intent.replaceExtras(pae.extras);
12515            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12516                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12517                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12518            closeSystemDialogs("assist");
12519            try {
12520                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12521            } catch (ActivityNotFoundException e) {
12522                Slog.w(TAG, "No activity to handle assist action.", e);
12523            }
12524        } finally {
12525            Binder.restoreCallingIdentity(ident);
12526        }
12527    }
12528
12529    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12530            Bundle args) {
12531        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12532                true /* focused */, true /* newSessionId */,
12533                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12534    }
12535
12536    public void registerProcessObserver(IProcessObserver observer) {
12537        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12538                "registerProcessObserver()");
12539        synchronized (this) {
12540            mProcessObservers.register(observer);
12541        }
12542    }
12543
12544    @Override
12545    public void unregisterProcessObserver(IProcessObserver observer) {
12546        synchronized (this) {
12547            mProcessObservers.unregister(observer);
12548        }
12549    }
12550
12551    @Override
12552    public void registerUidObserver(IUidObserver observer, int which) {
12553        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12554                "registerUidObserver()");
12555        synchronized (this) {
12556            mUidObservers.register(observer, which);
12557        }
12558    }
12559
12560    @Override
12561    public void unregisterUidObserver(IUidObserver observer) {
12562        synchronized (this) {
12563            mUidObservers.unregister(observer);
12564        }
12565    }
12566
12567    @Override
12568    public boolean convertFromTranslucent(IBinder token) {
12569        final long origId = Binder.clearCallingIdentity();
12570        try {
12571            synchronized (this) {
12572                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12573                if (r == null) {
12574                    return false;
12575                }
12576                final boolean translucentChanged = r.changeWindowTranslucency(true);
12577                if (translucentChanged) {
12578                    r.task.stack.releaseBackgroundResources(r);
12579                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12580                }
12581                mWindowManager.setAppFullscreen(token, true);
12582                return translucentChanged;
12583            }
12584        } finally {
12585            Binder.restoreCallingIdentity(origId);
12586        }
12587    }
12588
12589    @Override
12590    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12591        final long origId = Binder.clearCallingIdentity();
12592        try {
12593            synchronized (this) {
12594                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12595                if (r == null) {
12596                    return false;
12597                }
12598                int index = r.task.mActivities.lastIndexOf(r);
12599                if (index > 0) {
12600                    ActivityRecord under = r.task.mActivities.get(index - 1);
12601                    under.returningOptions = options;
12602                }
12603                final boolean translucentChanged = r.changeWindowTranslucency(false);
12604                if (translucentChanged) {
12605                    r.task.stack.convertActivityToTranslucent(r);
12606                }
12607                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12608                mWindowManager.setAppFullscreen(token, false);
12609                return translucentChanged;
12610            }
12611        } finally {
12612            Binder.restoreCallingIdentity(origId);
12613        }
12614    }
12615
12616    @Override
12617    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12618        final long origId = Binder.clearCallingIdentity();
12619        try {
12620            synchronized (this) {
12621                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12622                if (r != null) {
12623                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12624                }
12625            }
12626            return false;
12627        } finally {
12628            Binder.restoreCallingIdentity(origId);
12629        }
12630    }
12631
12632    @Override
12633    public boolean isBackgroundVisibleBehind(IBinder token) {
12634        final long origId = Binder.clearCallingIdentity();
12635        try {
12636            synchronized (this) {
12637                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12638                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12639                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12640                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12641                return visible;
12642            }
12643        } finally {
12644            Binder.restoreCallingIdentity(origId);
12645        }
12646    }
12647
12648    @Override
12649    public ActivityOptions getActivityOptions(IBinder token) {
12650        final long origId = Binder.clearCallingIdentity();
12651        try {
12652            synchronized (this) {
12653                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12654                if (r != null) {
12655                    final ActivityOptions activityOptions = r.pendingOptions;
12656                    r.pendingOptions = null;
12657                    return activityOptions;
12658                }
12659                return null;
12660            }
12661        } finally {
12662            Binder.restoreCallingIdentity(origId);
12663        }
12664    }
12665
12666    @Override
12667    public void setImmersive(IBinder token, boolean immersive) {
12668        synchronized(this) {
12669            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12670            if (r == null) {
12671                throw new IllegalArgumentException();
12672            }
12673            r.immersive = immersive;
12674
12675            // update associated state if we're frontmost
12676            if (r == mFocusedActivity) {
12677                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12678                applyUpdateLockStateLocked(r);
12679            }
12680        }
12681    }
12682
12683    @Override
12684    public boolean isImmersive(IBinder token) {
12685        synchronized (this) {
12686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12687            if (r == null) {
12688                throw new IllegalArgumentException();
12689            }
12690            return r.immersive;
12691        }
12692    }
12693
12694    public void setVrThread(int tid) {
12695        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12696            throw new UnsupportedOperationException("VR mode not supported on this device!");
12697        }
12698
12699        synchronized (this) {
12700            ProcessRecord proc;
12701            synchronized (mPidsSelfLocked) {
12702                final int pid = Binder.getCallingPid();
12703                proc = mPidsSelfLocked.get(pid);
12704
12705                if (proc != null && mInVrMode && tid >= 0) {
12706                    // ensure the tid belongs to the process
12707                    if (!Process.isThreadInProcess(pid, tid)) {
12708                        throw new IllegalArgumentException("VR thread does not belong to process");
12709                    }
12710
12711                    // reset existing VR thread to CFS if this thread still exists and belongs to
12712                    // the calling process
12713                    if (proc.vrThreadTid != 0
12714                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12715                        try {
12716                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12717                        } catch (IllegalArgumentException e) {
12718                            // Ignore this.  Only occurs in race condition where previous VR thread
12719                            // was destroyed during this method call.
12720                        }
12721                    }
12722
12723                    proc.vrThreadTid = tid;
12724
12725                    // promote to FIFO now if the tid is non-zero
12726                    try {
12727                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12728                            proc.vrThreadTid > 0) {
12729                            Process.setThreadScheduler(proc.vrThreadTid,
12730                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12731                        }
12732                    } catch (IllegalArgumentException e) {
12733                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12734                               + " not exist:\n" + e);
12735                    }
12736                }
12737            }
12738        }
12739    }
12740
12741    @Override
12742    public void setRenderThread(int tid) {
12743        synchronized (this) {
12744            ProcessRecord proc;
12745            synchronized (mPidsSelfLocked) {
12746                int pid = Binder.getCallingPid();
12747                proc = mPidsSelfLocked.get(pid);
12748                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12749                    // ensure the tid belongs to the process
12750                    if (!Process.isThreadInProcess(pid, tid)) {
12751                        throw new IllegalArgumentException(
12752                            "Render thread does not belong to process");
12753                    }
12754                    proc.renderThreadTid = tid;
12755                    if (DEBUG_OOM_ADJ) {
12756                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12757                    }
12758                    // promote to FIFO now
12759                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12760                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12761                        if (mUseFifoUiScheduling) {
12762                            Process.setThreadScheduler(proc.renderThreadTid,
12763                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12764                        } else {
12765                            Process.setThreadPriority(proc.renderThreadTid, -10);
12766                        }
12767                    }
12768                } else {
12769                    if (DEBUG_OOM_ADJ) {
12770                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12771                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12772                               mUseFifoUiScheduling);
12773                    }
12774                }
12775            }
12776        }
12777    }
12778
12779    @Override
12780    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12781        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12782            throw new UnsupportedOperationException("VR mode not supported on this device!");
12783        }
12784
12785        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12786
12787        ActivityRecord r;
12788        synchronized (this) {
12789            r = ActivityRecord.isInStackLocked(token);
12790        }
12791
12792        if (r == null) {
12793            throw new IllegalArgumentException();
12794        }
12795
12796        int err;
12797        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12798                VrManagerInternal.NO_ERROR) {
12799            return err;
12800        }
12801
12802        synchronized(this) {
12803            r.requestedVrComponent = (enabled) ? packageName : null;
12804
12805            // Update associated state if this activity is currently focused
12806            if (r == mFocusedActivity) {
12807                applyUpdateVrModeLocked(r);
12808            }
12809            return 0;
12810        }
12811    }
12812
12813    @Override
12814    public boolean isVrModePackageEnabled(ComponentName packageName) {
12815        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12816            throw new UnsupportedOperationException("VR mode not supported on this device!");
12817        }
12818
12819        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12820
12821        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12822                VrManagerInternal.NO_ERROR;
12823    }
12824
12825    public boolean isTopActivityImmersive() {
12826        enforceNotIsolatedCaller("startActivity");
12827        synchronized (this) {
12828            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12829            return (r != null) ? r.immersive : false;
12830        }
12831    }
12832
12833    @Override
12834    public boolean isTopOfTask(IBinder token) {
12835        synchronized (this) {
12836            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12837            if (r == null) {
12838                throw new IllegalArgumentException();
12839            }
12840            return r.task.getTopActivity() == r;
12841        }
12842    }
12843
12844    @Override
12845    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12846        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12847            String msg = "Permission Denial: setHasTopUi() from pid="
12848                    + Binder.getCallingPid()
12849                    + ", uid=" + Binder.getCallingUid()
12850                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12851            Slog.w(TAG, msg);
12852            throw new SecurityException(msg);
12853        }
12854        final int pid = Binder.getCallingPid();
12855        final long origId = Binder.clearCallingIdentity();
12856        try {
12857            synchronized (this) {
12858                boolean changed = false;
12859                ProcessRecord pr;
12860                synchronized (mPidsSelfLocked) {
12861                    pr = mPidsSelfLocked.get(pid);
12862                    if (pr == null) {
12863                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12864                        return;
12865                    }
12866                    if (pr.hasTopUi != hasTopUi) {
12867                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12868                        pr.hasTopUi = hasTopUi;
12869                        changed = true;
12870                    }
12871                }
12872                if (changed) {
12873                    updateOomAdjLocked(pr);
12874                }
12875            }
12876        } finally {
12877            Binder.restoreCallingIdentity(origId);
12878        }
12879    }
12880
12881    public final void enterSafeMode() {
12882        synchronized(this) {
12883            // It only makes sense to do this before the system is ready
12884            // and started launching other packages.
12885            if (!mSystemReady) {
12886                try {
12887                    AppGlobals.getPackageManager().enterSafeMode();
12888                } catch (RemoteException e) {
12889                }
12890            }
12891
12892            mSafeMode = true;
12893        }
12894    }
12895
12896    public final void showSafeModeOverlay() {
12897        View v = LayoutInflater.from(mContext).inflate(
12898                com.android.internal.R.layout.safe_mode, null);
12899        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12900        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12901        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12902        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12903        lp.gravity = Gravity.BOTTOM | Gravity.START;
12904        lp.format = v.getBackground().getOpacity();
12905        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12906                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12907        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12908        ((WindowManager)mContext.getSystemService(
12909                Context.WINDOW_SERVICE)).addView(v, lp);
12910    }
12911
12912    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12913        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12914            return;
12915        }
12916        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12917        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12918        synchronized (stats) {
12919            if (mBatteryStatsService.isOnBattery()) {
12920                mBatteryStatsService.enforceCallingPermission();
12921                int MY_UID = Binder.getCallingUid();
12922                final int uid;
12923                if (sender == null) {
12924                    uid = sourceUid;
12925                } else {
12926                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12927                }
12928                BatteryStatsImpl.Uid.Pkg pkg =
12929                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12930                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12931                pkg.noteWakeupAlarmLocked(tag);
12932            }
12933        }
12934    }
12935
12936    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12937        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12938            return;
12939        }
12940        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12941        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12942        synchronized (stats) {
12943            mBatteryStatsService.enforceCallingPermission();
12944            int MY_UID = Binder.getCallingUid();
12945            final int uid;
12946            if (sender == null) {
12947                uid = sourceUid;
12948            } else {
12949                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12950            }
12951            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12952        }
12953    }
12954
12955    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12956        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12957            return;
12958        }
12959        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12960        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12961        synchronized (stats) {
12962            mBatteryStatsService.enforceCallingPermission();
12963            int MY_UID = Binder.getCallingUid();
12964            final int uid;
12965            if (sender == null) {
12966                uid = sourceUid;
12967            } else {
12968                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12969            }
12970            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12971        }
12972    }
12973
12974    public boolean killPids(int[] pids, String pReason, boolean secure) {
12975        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12976            throw new SecurityException("killPids only available to the system");
12977        }
12978        String reason = (pReason == null) ? "Unknown" : pReason;
12979        // XXX Note: don't acquire main activity lock here, because the window
12980        // manager calls in with its locks held.
12981
12982        boolean killed = false;
12983        synchronized (mPidsSelfLocked) {
12984            int worstType = 0;
12985            for (int i=0; i<pids.length; i++) {
12986                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12987                if (proc != null) {
12988                    int type = proc.setAdj;
12989                    if (type > worstType) {
12990                        worstType = type;
12991                    }
12992                }
12993            }
12994
12995            // If the worst oom_adj is somewhere in the cached proc LRU range,
12996            // then constrain it so we will kill all cached procs.
12997            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12998                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12999                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13000            }
13001
13002            // If this is not a secure call, don't let it kill processes that
13003            // are important.
13004            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13005                worstType = ProcessList.SERVICE_ADJ;
13006            }
13007
13008            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13009            for (int i=0; i<pids.length; i++) {
13010                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13011                if (proc == null) {
13012                    continue;
13013                }
13014                int adj = proc.setAdj;
13015                if (adj >= worstType && !proc.killedByAm) {
13016                    proc.kill(reason, true);
13017                    killed = true;
13018                }
13019            }
13020        }
13021        return killed;
13022    }
13023
13024    @Override
13025    public void killUid(int appId, int userId, String reason) {
13026        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13027        synchronized (this) {
13028            final long identity = Binder.clearCallingIdentity();
13029            try {
13030                killPackageProcessesLocked(null, appId, userId,
13031                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13032                        reason != null ? reason : "kill uid");
13033            } finally {
13034                Binder.restoreCallingIdentity(identity);
13035            }
13036        }
13037    }
13038
13039    @Override
13040    public boolean killProcessesBelowForeground(String reason) {
13041        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13042            throw new SecurityException("killProcessesBelowForeground() only available to system");
13043        }
13044
13045        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13046    }
13047
13048    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13049        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13050            throw new SecurityException("killProcessesBelowAdj() only available to system");
13051        }
13052
13053        boolean killed = false;
13054        synchronized (mPidsSelfLocked) {
13055            final int size = mPidsSelfLocked.size();
13056            for (int i = 0; i < size; i++) {
13057                final int pid = mPidsSelfLocked.keyAt(i);
13058                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13059                if (proc == null) continue;
13060
13061                final int adj = proc.setAdj;
13062                if (adj > belowAdj && !proc.killedByAm) {
13063                    proc.kill(reason, true);
13064                    killed = true;
13065                }
13066            }
13067        }
13068        return killed;
13069    }
13070
13071    @Override
13072    public void hang(final IBinder who, boolean allowRestart) {
13073        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13074                != PackageManager.PERMISSION_GRANTED) {
13075            throw new SecurityException("Requires permission "
13076                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13077        }
13078
13079        final IBinder.DeathRecipient death = new DeathRecipient() {
13080            @Override
13081            public void binderDied() {
13082                synchronized (this) {
13083                    notifyAll();
13084                }
13085            }
13086        };
13087
13088        try {
13089            who.linkToDeath(death, 0);
13090        } catch (RemoteException e) {
13091            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13092            return;
13093        }
13094
13095        synchronized (this) {
13096            Watchdog.getInstance().setAllowRestart(allowRestart);
13097            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13098            synchronized (death) {
13099                while (who.isBinderAlive()) {
13100                    try {
13101                        death.wait();
13102                    } catch (InterruptedException e) {
13103                    }
13104                }
13105            }
13106            Watchdog.getInstance().setAllowRestart(true);
13107        }
13108    }
13109
13110    @Override
13111    public void restart() {
13112        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13113                != PackageManager.PERMISSION_GRANTED) {
13114            throw new SecurityException("Requires permission "
13115                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13116        }
13117
13118        Log.i(TAG, "Sending shutdown broadcast...");
13119
13120        BroadcastReceiver br = new BroadcastReceiver() {
13121            @Override public void onReceive(Context context, Intent intent) {
13122                // Now the broadcast is done, finish up the low-level shutdown.
13123                Log.i(TAG, "Shutting down activity manager...");
13124                shutdown(10000);
13125                Log.i(TAG, "Shutdown complete, restarting!");
13126                Process.killProcess(Process.myPid());
13127                System.exit(10);
13128            }
13129        };
13130
13131        // First send the high-level shut down broadcast.
13132        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13133        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13134        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13135        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13136        mContext.sendOrderedBroadcastAsUser(intent,
13137                UserHandle.ALL, null, br, mHandler, 0, null, null);
13138        */
13139        br.onReceive(mContext, intent);
13140    }
13141
13142    private long getLowRamTimeSinceIdle(long now) {
13143        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13144    }
13145
13146    @Override
13147    public void performIdleMaintenance() {
13148        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13149                != PackageManager.PERMISSION_GRANTED) {
13150            throw new SecurityException("Requires permission "
13151                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13152        }
13153
13154        synchronized (this) {
13155            final long now = SystemClock.uptimeMillis();
13156            final long timeSinceLastIdle = now - mLastIdleTime;
13157            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13158            mLastIdleTime = now;
13159            mLowRamTimeSinceLastIdle = 0;
13160            if (mLowRamStartTime != 0) {
13161                mLowRamStartTime = now;
13162            }
13163
13164            StringBuilder sb = new StringBuilder(128);
13165            sb.append("Idle maintenance over ");
13166            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13167            sb.append(" low RAM for ");
13168            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13169            Slog.i(TAG, sb.toString());
13170
13171            // If at least 1/3 of our time since the last idle period has been spent
13172            // with RAM low, then we want to kill processes.
13173            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13174
13175            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13176                ProcessRecord proc = mLruProcesses.get(i);
13177                if (proc.notCachedSinceIdle) {
13178                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13179                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13180                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13181                        if (doKilling && proc.initialIdlePss != 0
13182                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13183                            sb = new StringBuilder(128);
13184                            sb.append("Kill");
13185                            sb.append(proc.processName);
13186                            sb.append(" in idle maint: pss=");
13187                            sb.append(proc.lastPss);
13188                            sb.append(", swapPss=");
13189                            sb.append(proc.lastSwapPss);
13190                            sb.append(", initialPss=");
13191                            sb.append(proc.initialIdlePss);
13192                            sb.append(", period=");
13193                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13194                            sb.append(", lowRamPeriod=");
13195                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13196                            Slog.wtfQuiet(TAG, sb.toString());
13197                            proc.kill("idle maint (pss " + proc.lastPss
13198                                    + " from " + proc.initialIdlePss + ")", true);
13199                        }
13200                    }
13201                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13202                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13203                    proc.notCachedSinceIdle = true;
13204                    proc.initialIdlePss = 0;
13205                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13206                            mTestPssMode, isSleepingLocked(), now);
13207                }
13208            }
13209
13210            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13211            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13212        }
13213    }
13214
13215    @Override
13216    public void sendIdleJobTrigger() {
13217        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13218                != PackageManager.PERMISSION_GRANTED) {
13219            throw new SecurityException("Requires permission "
13220                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13221        }
13222
13223        final long ident = Binder.clearCallingIdentity();
13224        try {
13225            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13226                    .setPackage("android")
13227                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13228            broadcastIntent(null, intent, null, null, 0, null, null, null,
13229                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13230        } finally {
13231            Binder.restoreCallingIdentity(ident);
13232        }
13233    }
13234
13235    private void retrieveSettings() {
13236        final ContentResolver resolver = mContext.getContentResolver();
13237        final boolean freeformWindowManagement =
13238                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13239                        || Settings.Global.getInt(
13240                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13241        final boolean supportsPictureInPicture =
13242                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13243
13244        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13245        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13246        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13247        final boolean alwaysFinishActivities =
13248                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13249        final boolean lenientBackgroundCheck =
13250                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13251        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13252        final boolean forceResizable = Settings.Global.getInt(
13253                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13254        final boolean supportsLeanbackOnly =
13255                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13256
13257        // Transfer any global setting for forcing RTL layout, into a System Property
13258        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13259
13260        final Configuration configuration = new Configuration();
13261        Settings.System.getConfiguration(resolver, configuration);
13262        if (forceRtl) {
13263            // This will take care of setting the correct layout direction flags
13264            configuration.setLayoutDirection(configuration.locale);
13265        }
13266
13267        synchronized (this) {
13268            mDebugApp = mOrigDebugApp = debugApp;
13269            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13270            mAlwaysFinishActivities = alwaysFinishActivities;
13271            mLenientBackgroundCheck = lenientBackgroundCheck;
13272            mSupportsLeanbackOnly = supportsLeanbackOnly;
13273            mForceResizableActivities = forceResizable;
13274            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13275            if (supportsMultiWindow || forceResizable) {
13276                mSupportsMultiWindow = true;
13277                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13278                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13279            } else {
13280                mSupportsMultiWindow = false;
13281                mSupportsFreeformWindowManagement = false;
13282                mSupportsPictureInPicture = false;
13283            }
13284            // This happens before any activities are started, so we can
13285            // change mConfiguration in-place.
13286            updateConfigurationLocked(configuration, null, true);
13287            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13288                    "Initial config: " + mConfiguration);
13289
13290            // Load resources only after the current configuration has been set.
13291            final Resources res = mContext.getResources();
13292            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13293            mThumbnailWidth = res.getDimensionPixelSize(
13294                    com.android.internal.R.dimen.thumbnail_width);
13295            mThumbnailHeight = res.getDimensionPixelSize(
13296                    com.android.internal.R.dimen.thumbnail_height);
13297            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13298                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13299            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13300                    com.android.internal.R.string.config_appsNotReportingCrashes));
13301            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13302                mFullscreenThumbnailScale = (float) res
13303                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13304                    (float) mConfiguration.screenWidthDp;
13305            } else {
13306                mFullscreenThumbnailScale = res.getFraction(
13307                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13308            }
13309        }
13310    }
13311
13312    public boolean testIsSystemReady() {
13313        // no need to synchronize(this) just to read & return the value
13314        return mSystemReady;
13315    }
13316
13317    public void systemReady(final Runnable goingCallback) {
13318        synchronized(this) {
13319            if (mSystemReady) {
13320                // If we're done calling all the receivers, run the next "boot phase" passed in
13321                // by the SystemServer
13322                if (goingCallback != null) {
13323                    goingCallback.run();
13324                }
13325                return;
13326            }
13327
13328            mLocalDeviceIdleController
13329                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13330
13331            // Make sure we have the current profile info, since it is needed for security checks.
13332            mUserController.onSystemReady();
13333            mRecentTasks.onSystemReadyLocked();
13334            mAppOpsService.systemReady();
13335            mSystemReady = true;
13336        }
13337
13338        ArrayList<ProcessRecord> procsToKill = null;
13339        synchronized(mPidsSelfLocked) {
13340            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13341                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13342                if (!isAllowedWhileBooting(proc.info)){
13343                    if (procsToKill == null) {
13344                        procsToKill = new ArrayList<ProcessRecord>();
13345                    }
13346                    procsToKill.add(proc);
13347                }
13348            }
13349        }
13350
13351        synchronized(this) {
13352            if (procsToKill != null) {
13353                for (int i=procsToKill.size()-1; i>=0; i--) {
13354                    ProcessRecord proc = procsToKill.get(i);
13355                    Slog.i(TAG, "Removing system update proc: " + proc);
13356                    removeProcessLocked(proc, true, false, "system update done");
13357                }
13358            }
13359
13360            // Now that we have cleaned up any update processes, we
13361            // are ready to start launching real processes and know that
13362            // we won't trample on them any more.
13363            mProcessesReady = true;
13364        }
13365
13366        Slog.i(TAG, "System now ready");
13367        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13368            SystemClock.uptimeMillis());
13369
13370        synchronized(this) {
13371            // Make sure we have no pre-ready processes sitting around.
13372
13373            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13374                ResolveInfo ri = mContext.getPackageManager()
13375                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13376                                STOCK_PM_FLAGS);
13377                CharSequence errorMsg = null;
13378                if (ri != null) {
13379                    ActivityInfo ai = ri.activityInfo;
13380                    ApplicationInfo app = ai.applicationInfo;
13381                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13382                        mTopAction = Intent.ACTION_FACTORY_TEST;
13383                        mTopData = null;
13384                        mTopComponent = new ComponentName(app.packageName,
13385                                ai.name);
13386                    } else {
13387                        errorMsg = mContext.getResources().getText(
13388                                com.android.internal.R.string.factorytest_not_system);
13389                    }
13390                } else {
13391                    errorMsg = mContext.getResources().getText(
13392                            com.android.internal.R.string.factorytest_no_action);
13393                }
13394                if (errorMsg != null) {
13395                    mTopAction = null;
13396                    mTopData = null;
13397                    mTopComponent = null;
13398                    Message msg = Message.obtain();
13399                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13400                    msg.getData().putCharSequence("msg", errorMsg);
13401                    mUiHandler.sendMessage(msg);
13402                }
13403            }
13404        }
13405
13406        retrieveSettings();
13407        final int currentUserId;
13408        synchronized (this) {
13409            currentUserId = mUserController.getCurrentUserIdLocked();
13410            readGrantedUriPermissionsLocked();
13411        }
13412
13413        if (goingCallback != null) goingCallback.run();
13414
13415        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13416                Integer.toString(currentUserId), currentUserId);
13417        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13418                Integer.toString(currentUserId), currentUserId);
13419        mSystemServiceManager.startUser(currentUserId);
13420
13421        synchronized (this) {
13422            // Only start up encryption-aware persistent apps; once user is
13423            // unlocked we'll come back around and start unaware apps
13424            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13425
13426            // Start up initial activity.
13427            mBooting = true;
13428            // Enable home activity for system user, so that the system can always boot
13429            if (UserManager.isSplitSystemUser()) {
13430                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13431                try {
13432                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13433                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13434                            UserHandle.USER_SYSTEM);
13435                } catch (RemoteException e) {
13436                    throw e.rethrowAsRuntimeException();
13437                }
13438            }
13439            startHomeActivityLocked(currentUserId, "systemReady");
13440
13441            try {
13442                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13443                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13444                            + " data partition or your device will be unstable.");
13445                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13446                }
13447            } catch (RemoteException e) {
13448            }
13449
13450            if (!Build.isBuildConsistent()) {
13451                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13452                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13453            }
13454
13455            long ident = Binder.clearCallingIdentity();
13456            try {
13457                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13458                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13459                        | Intent.FLAG_RECEIVER_FOREGROUND);
13460                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13461                broadcastIntentLocked(null, null, intent,
13462                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13463                        null, false, false, MY_PID, Process.SYSTEM_UID,
13464                        currentUserId);
13465                intent = new Intent(Intent.ACTION_USER_STARTING);
13466                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13467                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13468                broadcastIntentLocked(null, null, intent,
13469                        null, new IIntentReceiver.Stub() {
13470                            @Override
13471                            public void performReceive(Intent intent, int resultCode, String data,
13472                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13473                                    throws RemoteException {
13474                            }
13475                        }, 0, null, null,
13476                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13477                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13478            } catch (Throwable t) {
13479                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13480            } finally {
13481                Binder.restoreCallingIdentity(ident);
13482            }
13483            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13484            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13485        }
13486    }
13487
13488    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13489        synchronized (this) {
13490            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13491        }
13492    }
13493
13494    void skipCurrentReceiverLocked(ProcessRecord app) {
13495        for (BroadcastQueue queue : mBroadcastQueues) {
13496            queue.skipCurrentReceiverLocked(app);
13497        }
13498    }
13499
13500    /**
13501     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13502     * The application process will exit immediately after this call returns.
13503     * @param app object of the crashing app, null for the system server
13504     * @param crashInfo describing the exception
13505     */
13506    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13507        ProcessRecord r = findAppProcess(app, "Crash");
13508        final String processName = app == null ? "system_server"
13509                : (r == null ? "unknown" : r.processName);
13510
13511        handleApplicationCrashInner("crash", r, processName, crashInfo);
13512    }
13513
13514    /* Native crash reporting uses this inner version because it needs to be somewhat
13515     * decoupled from the AM-managed cleanup lifecycle
13516     */
13517    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13518            ApplicationErrorReport.CrashInfo crashInfo) {
13519        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13520                UserHandle.getUserId(Binder.getCallingUid()), processName,
13521                r == null ? -1 : r.info.flags,
13522                crashInfo.exceptionClassName,
13523                crashInfo.exceptionMessage,
13524                crashInfo.throwFileName,
13525                crashInfo.throwLineNumber);
13526
13527        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13528
13529        mAppErrors.crashApplication(r, crashInfo);
13530    }
13531
13532    public void handleApplicationStrictModeViolation(
13533            IBinder app,
13534            int violationMask,
13535            StrictMode.ViolationInfo info) {
13536        ProcessRecord r = findAppProcess(app, "StrictMode");
13537        if (r == null) {
13538            return;
13539        }
13540
13541        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13542            Integer stackFingerprint = info.hashCode();
13543            boolean logIt = true;
13544            synchronized (mAlreadyLoggedViolatedStacks) {
13545                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13546                    logIt = false;
13547                    // TODO: sub-sample into EventLog for these, with
13548                    // the info.durationMillis?  Then we'd get
13549                    // the relative pain numbers, without logging all
13550                    // the stack traces repeatedly.  We'd want to do
13551                    // likewise in the client code, which also does
13552                    // dup suppression, before the Binder call.
13553                } else {
13554                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13555                        mAlreadyLoggedViolatedStacks.clear();
13556                    }
13557                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13558                }
13559            }
13560            if (logIt) {
13561                logStrictModeViolationToDropBox(r, info);
13562            }
13563        }
13564
13565        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13566            AppErrorResult result = new AppErrorResult();
13567            synchronized (this) {
13568                final long origId = Binder.clearCallingIdentity();
13569
13570                Message msg = Message.obtain();
13571                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13572                HashMap<String, Object> data = new HashMap<String, Object>();
13573                data.put("result", result);
13574                data.put("app", r);
13575                data.put("violationMask", violationMask);
13576                data.put("info", info);
13577                msg.obj = data;
13578                mUiHandler.sendMessage(msg);
13579
13580                Binder.restoreCallingIdentity(origId);
13581            }
13582            int res = result.get();
13583            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13584        }
13585    }
13586
13587    // Depending on the policy in effect, there could be a bunch of
13588    // these in quick succession so we try to batch these together to
13589    // minimize disk writes, number of dropbox entries, and maximize
13590    // compression, by having more fewer, larger records.
13591    private void logStrictModeViolationToDropBox(
13592            ProcessRecord process,
13593            StrictMode.ViolationInfo info) {
13594        if (info == null) {
13595            return;
13596        }
13597        final boolean isSystemApp = process == null ||
13598                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13599                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13600        final String processName = process == null ? "unknown" : process.processName;
13601        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13602        final DropBoxManager dbox = (DropBoxManager)
13603                mContext.getSystemService(Context.DROPBOX_SERVICE);
13604
13605        // Exit early if the dropbox isn't configured to accept this report type.
13606        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13607
13608        boolean bufferWasEmpty;
13609        boolean needsFlush;
13610        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13611        synchronized (sb) {
13612            bufferWasEmpty = sb.length() == 0;
13613            appendDropBoxProcessHeaders(process, processName, sb);
13614            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13615            sb.append("System-App: ").append(isSystemApp).append("\n");
13616            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13617            if (info.violationNumThisLoop != 0) {
13618                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13619            }
13620            if (info.numAnimationsRunning != 0) {
13621                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13622            }
13623            if (info.broadcastIntentAction != null) {
13624                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13625            }
13626            if (info.durationMillis != -1) {
13627                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13628            }
13629            if (info.numInstances != -1) {
13630                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13631            }
13632            if (info.tags != null) {
13633                for (String tag : info.tags) {
13634                    sb.append("Span-Tag: ").append(tag).append("\n");
13635                }
13636            }
13637            sb.append("\n");
13638            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13639                sb.append(info.crashInfo.stackTrace);
13640                sb.append("\n");
13641            }
13642            if (info.message != null) {
13643                sb.append(info.message);
13644                sb.append("\n");
13645            }
13646
13647            // Only buffer up to ~64k.  Various logging bits truncate
13648            // things at 128k.
13649            needsFlush = (sb.length() > 64 * 1024);
13650        }
13651
13652        // Flush immediately if the buffer's grown too large, or this
13653        // is a non-system app.  Non-system apps are isolated with a
13654        // different tag & policy and not batched.
13655        //
13656        // Batching is useful during internal testing with
13657        // StrictMode settings turned up high.  Without batching,
13658        // thousands of separate files could be created on boot.
13659        if (!isSystemApp || needsFlush) {
13660            new Thread("Error dump: " + dropboxTag) {
13661                @Override
13662                public void run() {
13663                    String report;
13664                    synchronized (sb) {
13665                        report = sb.toString();
13666                        sb.delete(0, sb.length());
13667                        sb.trimToSize();
13668                    }
13669                    if (report.length() != 0) {
13670                        dbox.addText(dropboxTag, report);
13671                    }
13672                }
13673            }.start();
13674            return;
13675        }
13676
13677        // System app batching:
13678        if (!bufferWasEmpty) {
13679            // An existing dropbox-writing thread is outstanding, so
13680            // we don't need to start it up.  The existing thread will
13681            // catch the buffer appends we just did.
13682            return;
13683        }
13684
13685        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13686        // (After this point, we shouldn't access AMS internal data structures.)
13687        new Thread("Error dump: " + dropboxTag) {
13688            @Override
13689            public void run() {
13690                // 5 second sleep to let stacks arrive and be batched together
13691                try {
13692                    Thread.sleep(5000);  // 5 seconds
13693                } catch (InterruptedException e) {}
13694
13695                String errorReport;
13696                synchronized (mStrictModeBuffer) {
13697                    errorReport = mStrictModeBuffer.toString();
13698                    if (errorReport.length() == 0) {
13699                        return;
13700                    }
13701                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13702                    mStrictModeBuffer.trimToSize();
13703                }
13704                dbox.addText(dropboxTag, errorReport);
13705            }
13706        }.start();
13707    }
13708
13709    /**
13710     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13711     * @param app object of the crashing app, null for the system server
13712     * @param tag reported by the caller
13713     * @param system whether this wtf is coming from the system
13714     * @param crashInfo describing the context of the error
13715     * @return true if the process should exit immediately (WTF is fatal)
13716     */
13717    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13718            final ApplicationErrorReport.CrashInfo crashInfo) {
13719        final int callingUid = Binder.getCallingUid();
13720        final int callingPid = Binder.getCallingPid();
13721
13722        if (system) {
13723            // If this is coming from the system, we could very well have low-level
13724            // system locks held, so we want to do this all asynchronously.  And we
13725            // never want this to become fatal, so there is that too.
13726            mHandler.post(new Runnable() {
13727                @Override public void run() {
13728                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13729                }
13730            });
13731            return false;
13732        }
13733
13734        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13735                crashInfo);
13736
13737        if (r != null && r.pid != Process.myPid() &&
13738                Settings.Global.getInt(mContext.getContentResolver(),
13739                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13740            mAppErrors.crashApplication(r, crashInfo);
13741            return true;
13742        } else {
13743            return false;
13744        }
13745    }
13746
13747    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13748            final ApplicationErrorReport.CrashInfo crashInfo) {
13749        final ProcessRecord r = findAppProcess(app, "WTF");
13750        final String processName = app == null ? "system_server"
13751                : (r == null ? "unknown" : r.processName);
13752
13753        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13754                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13755
13756        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13757
13758        return r;
13759    }
13760
13761    /**
13762     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13763     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13764     */
13765    private ProcessRecord findAppProcess(IBinder app, String reason) {
13766        if (app == null) {
13767            return null;
13768        }
13769
13770        synchronized (this) {
13771            final int NP = mProcessNames.getMap().size();
13772            for (int ip=0; ip<NP; ip++) {
13773                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13774                final int NA = apps.size();
13775                for (int ia=0; ia<NA; ia++) {
13776                    ProcessRecord p = apps.valueAt(ia);
13777                    if (p.thread != null && p.thread.asBinder() == app) {
13778                        return p;
13779                    }
13780                }
13781            }
13782
13783            Slog.w(TAG, "Can't find mystery application for " + reason
13784                    + " from pid=" + Binder.getCallingPid()
13785                    + " uid=" + Binder.getCallingUid() + ": " + app);
13786            return null;
13787        }
13788    }
13789
13790    /**
13791     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13792     * to append various headers to the dropbox log text.
13793     */
13794    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13795            StringBuilder sb) {
13796        // Watchdog thread ends up invoking this function (with
13797        // a null ProcessRecord) to add the stack file to dropbox.
13798        // Do not acquire a lock on this (am) in such cases, as it
13799        // could cause a potential deadlock, if and when watchdog
13800        // is invoked due to unavailability of lock on am and it
13801        // would prevent watchdog from killing system_server.
13802        if (process == null) {
13803            sb.append("Process: ").append(processName).append("\n");
13804            return;
13805        }
13806        // Note: ProcessRecord 'process' is guarded by the service
13807        // instance.  (notably process.pkgList, which could otherwise change
13808        // concurrently during execution of this method)
13809        synchronized (this) {
13810            sb.append("Process: ").append(processName).append("\n");
13811            int flags = process.info.flags;
13812            IPackageManager pm = AppGlobals.getPackageManager();
13813            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13814            for (int ip=0; ip<process.pkgList.size(); ip++) {
13815                String pkg = process.pkgList.keyAt(ip);
13816                sb.append("Package: ").append(pkg);
13817                try {
13818                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13819                    if (pi != null) {
13820                        sb.append(" v").append(pi.versionCode);
13821                        if (pi.versionName != null) {
13822                            sb.append(" (").append(pi.versionName).append(")");
13823                        }
13824                    }
13825                } catch (RemoteException e) {
13826                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13827                }
13828                sb.append("\n");
13829            }
13830        }
13831    }
13832
13833    private static String processClass(ProcessRecord process) {
13834        if (process == null || process.pid == MY_PID) {
13835            return "system_server";
13836        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13837            return "system_app";
13838        } else {
13839            return "data_app";
13840        }
13841    }
13842
13843    private volatile long mWtfClusterStart;
13844    private volatile int mWtfClusterCount;
13845
13846    /**
13847     * Write a description of an error (crash, WTF, ANR) to the drop box.
13848     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13849     * @param process which caused the error, null means the system server
13850     * @param activity which triggered the error, null if unknown
13851     * @param parent activity related to the error, null if unknown
13852     * @param subject line related to the error, null if absent
13853     * @param report in long form describing the error, null if absent
13854     * @param dataFile text file to include in the report, null if none
13855     * @param crashInfo giving an application stack trace, null if absent
13856     */
13857    public void addErrorToDropBox(String eventType,
13858            ProcessRecord process, String processName, ActivityRecord activity,
13859            ActivityRecord parent, String subject,
13860            final String report, final File dataFile,
13861            final ApplicationErrorReport.CrashInfo crashInfo) {
13862        // NOTE -- this must never acquire the ActivityManagerService lock,
13863        // otherwise the watchdog may be prevented from resetting the system.
13864
13865        final String dropboxTag = processClass(process) + "_" + eventType;
13866        final DropBoxManager dbox = (DropBoxManager)
13867                mContext.getSystemService(Context.DROPBOX_SERVICE);
13868
13869        // Exit early if the dropbox isn't configured to accept this report type.
13870        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13871
13872        // Rate-limit how often we're willing to do the heavy lifting below to
13873        // collect and record logs; currently 5 logs per 10 second period.
13874        final long now = SystemClock.elapsedRealtime();
13875        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13876            mWtfClusterStart = now;
13877            mWtfClusterCount = 1;
13878        } else {
13879            if (mWtfClusterCount++ >= 5) return;
13880        }
13881
13882        final StringBuilder sb = new StringBuilder(1024);
13883        appendDropBoxProcessHeaders(process, processName, sb);
13884        if (process != null) {
13885            sb.append("Foreground: ")
13886                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13887                    .append("\n");
13888        }
13889        if (activity != null) {
13890            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13891        }
13892        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13893            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13894        }
13895        if (parent != null && parent != activity) {
13896            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13897        }
13898        if (subject != null) {
13899            sb.append("Subject: ").append(subject).append("\n");
13900        }
13901        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13902        if (Debug.isDebuggerConnected()) {
13903            sb.append("Debugger: Connected\n");
13904        }
13905        sb.append("\n");
13906
13907        // Do the rest in a worker thread to avoid blocking the caller on I/O
13908        // (After this point, we shouldn't access AMS internal data structures.)
13909        Thread worker = new Thread("Error dump: " + dropboxTag) {
13910            @Override
13911            public void run() {
13912                if (report != null) {
13913                    sb.append(report);
13914                }
13915
13916                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13917                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13918                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13919                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13920
13921                if (dataFile != null && maxDataFileSize > 0) {
13922                    try {
13923                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13924                                    "\n\n[[TRUNCATED]]"));
13925                    } catch (IOException e) {
13926                        Slog.e(TAG, "Error reading " + dataFile, e);
13927                    }
13928                }
13929                if (crashInfo != null && crashInfo.stackTrace != null) {
13930                    sb.append(crashInfo.stackTrace);
13931                }
13932
13933                if (lines > 0) {
13934                    sb.append("\n");
13935
13936                    // Merge several logcat streams, and take the last N lines
13937                    InputStreamReader input = null;
13938                    try {
13939                        java.lang.Process logcat = new ProcessBuilder(
13940                                "/system/bin/timeout", "-k", "15s", "10s",
13941                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13942                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13943                                        .redirectErrorStream(true).start();
13944
13945                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13946                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13947                        input = new InputStreamReader(logcat.getInputStream());
13948
13949                        int num;
13950                        char[] buf = new char[8192];
13951                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13952                    } catch (IOException e) {
13953                        Slog.e(TAG, "Error running logcat", e);
13954                    } finally {
13955                        if (input != null) try { input.close(); } catch (IOException e) {}
13956                    }
13957                }
13958
13959                dbox.addText(dropboxTag, sb.toString());
13960            }
13961        };
13962
13963        if (process == null) {
13964            // If process is null, we are being called from some internal code
13965            // and may be about to die -- run this synchronously.
13966            worker.run();
13967        } else {
13968            worker.start();
13969        }
13970    }
13971
13972    @Override
13973    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13974        enforceNotIsolatedCaller("getProcessesInErrorState");
13975        // assume our apps are happy - lazy create the list
13976        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13977
13978        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13979                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13980        int userId = UserHandle.getUserId(Binder.getCallingUid());
13981
13982        synchronized (this) {
13983
13984            // iterate across all processes
13985            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13986                ProcessRecord app = mLruProcesses.get(i);
13987                if (!allUsers && app.userId != userId) {
13988                    continue;
13989                }
13990                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13991                    // This one's in trouble, so we'll generate a report for it
13992                    // crashes are higher priority (in case there's a crash *and* an anr)
13993                    ActivityManager.ProcessErrorStateInfo report = null;
13994                    if (app.crashing) {
13995                        report = app.crashingReport;
13996                    } else if (app.notResponding) {
13997                        report = app.notRespondingReport;
13998                    }
13999
14000                    if (report != null) {
14001                        if (errList == null) {
14002                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14003                        }
14004                        errList.add(report);
14005                    } else {
14006                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14007                                " crashing = " + app.crashing +
14008                                " notResponding = " + app.notResponding);
14009                    }
14010                }
14011            }
14012        }
14013
14014        return errList;
14015    }
14016
14017    static int procStateToImportance(int procState, int memAdj,
14018            ActivityManager.RunningAppProcessInfo currApp) {
14019        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14020        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14021            currApp.lru = memAdj;
14022        } else {
14023            currApp.lru = 0;
14024        }
14025        return imp;
14026    }
14027
14028    private void fillInProcMemInfo(ProcessRecord app,
14029            ActivityManager.RunningAppProcessInfo outInfo) {
14030        outInfo.pid = app.pid;
14031        outInfo.uid = app.info.uid;
14032        if (mHeavyWeightProcess == app) {
14033            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14034        }
14035        if (app.persistent) {
14036            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14037        }
14038        if (app.activities.size() > 0) {
14039            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14040        }
14041        outInfo.lastTrimLevel = app.trimMemoryLevel;
14042        int adj = app.curAdj;
14043        int procState = app.curProcState;
14044        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14045        outInfo.importanceReasonCode = app.adjTypeCode;
14046        outInfo.processState = app.curProcState;
14047    }
14048
14049    @Override
14050    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14051        enforceNotIsolatedCaller("getRunningAppProcesses");
14052
14053        final int callingUid = Binder.getCallingUid();
14054
14055        // Lazy instantiation of list
14056        List<ActivityManager.RunningAppProcessInfo> runList = null;
14057        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14058                callingUid) == PackageManager.PERMISSION_GRANTED;
14059        final int userId = UserHandle.getUserId(callingUid);
14060        final boolean allUids = isGetTasksAllowed(
14061                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14062
14063        synchronized (this) {
14064            // Iterate across all processes
14065            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14066                ProcessRecord app = mLruProcesses.get(i);
14067                if ((!allUsers && app.userId != userId)
14068                        || (!allUids && app.uid != callingUid)) {
14069                    continue;
14070                }
14071                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14072                    // Generate process state info for running application
14073                    ActivityManager.RunningAppProcessInfo currApp =
14074                        new ActivityManager.RunningAppProcessInfo(app.processName,
14075                                app.pid, app.getPackageList());
14076                    fillInProcMemInfo(app, currApp);
14077                    if (app.adjSource instanceof ProcessRecord) {
14078                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14079                        currApp.importanceReasonImportance =
14080                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14081                                        app.adjSourceProcState);
14082                    } else if (app.adjSource instanceof ActivityRecord) {
14083                        ActivityRecord r = (ActivityRecord)app.adjSource;
14084                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14085                    }
14086                    if (app.adjTarget instanceof ComponentName) {
14087                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14088                    }
14089                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14090                    //        + " lru=" + currApp.lru);
14091                    if (runList == null) {
14092                        runList = new ArrayList<>();
14093                    }
14094                    runList.add(currApp);
14095                }
14096            }
14097        }
14098        return runList;
14099    }
14100
14101    @Override
14102    public List<ApplicationInfo> getRunningExternalApplications() {
14103        enforceNotIsolatedCaller("getRunningExternalApplications");
14104        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14105        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14106        if (runningApps != null && runningApps.size() > 0) {
14107            Set<String> extList = new HashSet<String>();
14108            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14109                if (app.pkgList != null) {
14110                    for (String pkg : app.pkgList) {
14111                        extList.add(pkg);
14112                    }
14113                }
14114            }
14115            IPackageManager pm = AppGlobals.getPackageManager();
14116            for (String pkg : extList) {
14117                try {
14118                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14119                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14120                        retList.add(info);
14121                    }
14122                } catch (RemoteException e) {
14123                }
14124            }
14125        }
14126        return retList;
14127    }
14128
14129    @Override
14130    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14131        enforceNotIsolatedCaller("getMyMemoryState");
14132        synchronized (this) {
14133            ProcessRecord proc;
14134            synchronized (mPidsSelfLocked) {
14135                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14136            }
14137            fillInProcMemInfo(proc, outInfo);
14138        }
14139    }
14140
14141    @Override
14142    public int getMemoryTrimLevel() {
14143        enforceNotIsolatedCaller("getMyMemoryState");
14144        synchronized (this) {
14145            return mLastMemoryLevel;
14146        }
14147    }
14148
14149    @Override
14150    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14151            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14152        (new ActivityManagerShellCommand(this, false)).exec(
14153                this, in, out, err, args, resultReceiver);
14154    }
14155
14156    @Override
14157    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14158        if (checkCallingPermission(android.Manifest.permission.DUMP)
14159                != PackageManager.PERMISSION_GRANTED) {
14160            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14161                    + Binder.getCallingPid()
14162                    + ", uid=" + Binder.getCallingUid()
14163                    + " without permission "
14164                    + android.Manifest.permission.DUMP);
14165            return;
14166        }
14167
14168        boolean dumpAll = false;
14169        boolean dumpClient = false;
14170        boolean dumpCheckin = false;
14171        boolean dumpCheckinFormat = false;
14172        String dumpPackage = null;
14173
14174        int opti = 0;
14175        while (opti < args.length) {
14176            String opt = args[opti];
14177            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14178                break;
14179            }
14180            opti++;
14181            if ("-a".equals(opt)) {
14182                dumpAll = true;
14183            } else if ("-c".equals(opt)) {
14184                dumpClient = true;
14185            } else if ("-p".equals(opt)) {
14186                if (opti < args.length) {
14187                    dumpPackage = args[opti];
14188                    opti++;
14189                } else {
14190                    pw.println("Error: -p option requires package argument");
14191                    return;
14192                }
14193                dumpClient = true;
14194            } else if ("--checkin".equals(opt)) {
14195                dumpCheckin = dumpCheckinFormat = true;
14196            } else if ("-C".equals(opt)) {
14197                dumpCheckinFormat = true;
14198            } else if ("-h".equals(opt)) {
14199                ActivityManagerShellCommand.dumpHelp(pw, true);
14200                return;
14201            } else {
14202                pw.println("Unknown argument: " + opt + "; use -h for help");
14203            }
14204        }
14205
14206        long origId = Binder.clearCallingIdentity();
14207        boolean more = false;
14208        // Is the caller requesting to dump a particular piece of data?
14209        if (opti < args.length) {
14210            String cmd = args[opti];
14211            opti++;
14212            if ("activities".equals(cmd) || "a".equals(cmd)) {
14213                synchronized (this) {
14214                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14215                }
14216            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14217                synchronized (this) {
14218                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14219                }
14220            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14221                String[] newArgs;
14222                String name;
14223                if (opti >= args.length) {
14224                    name = null;
14225                    newArgs = EMPTY_STRING_ARRAY;
14226                } else {
14227                    dumpPackage = args[opti];
14228                    opti++;
14229                    newArgs = new String[args.length - opti];
14230                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14231                            args.length - opti);
14232                }
14233                synchronized (this) {
14234                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14235                }
14236            } else if ("broadcast-stats".equals(cmd)) {
14237                String[] newArgs;
14238                String name;
14239                if (opti >= args.length) {
14240                    name = null;
14241                    newArgs = EMPTY_STRING_ARRAY;
14242                } else {
14243                    dumpPackage = args[opti];
14244                    opti++;
14245                    newArgs = new String[args.length - opti];
14246                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14247                            args.length - opti);
14248                }
14249                synchronized (this) {
14250                    if (dumpCheckinFormat) {
14251                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14252                                dumpPackage);
14253                    } else {
14254                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14255                    }
14256                }
14257            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14258                String[] newArgs;
14259                String name;
14260                if (opti >= args.length) {
14261                    name = null;
14262                    newArgs = EMPTY_STRING_ARRAY;
14263                } else {
14264                    dumpPackage = args[opti];
14265                    opti++;
14266                    newArgs = new String[args.length - opti];
14267                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14268                            args.length - opti);
14269                }
14270                synchronized (this) {
14271                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14272                }
14273            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14274                String[] newArgs;
14275                String name;
14276                if (opti >= args.length) {
14277                    name = null;
14278                    newArgs = EMPTY_STRING_ARRAY;
14279                } else {
14280                    dumpPackage = args[opti];
14281                    opti++;
14282                    newArgs = new String[args.length - opti];
14283                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14284                            args.length - opti);
14285                }
14286                synchronized (this) {
14287                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14288                }
14289            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14290                synchronized (this) {
14291                    dumpOomLocked(fd, pw, args, opti, true);
14292                }
14293            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14294                synchronized (this) {
14295                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14296                }
14297            } else if ("provider".equals(cmd)) {
14298                String[] newArgs;
14299                String name;
14300                if (opti >= args.length) {
14301                    name = null;
14302                    newArgs = EMPTY_STRING_ARRAY;
14303                } else {
14304                    name = args[opti];
14305                    opti++;
14306                    newArgs = new String[args.length - opti];
14307                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14308                }
14309                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14310                    pw.println("No providers match: " + name);
14311                    pw.println("Use -h for help.");
14312                }
14313            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14314                synchronized (this) {
14315                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14316                }
14317            } else if ("service".equals(cmd)) {
14318                String[] newArgs;
14319                String name;
14320                if (opti >= args.length) {
14321                    name = null;
14322                    newArgs = EMPTY_STRING_ARRAY;
14323                } else {
14324                    name = args[opti];
14325                    opti++;
14326                    newArgs = new String[args.length - opti];
14327                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14328                            args.length - opti);
14329                }
14330                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14331                    pw.println("No services match: " + name);
14332                    pw.println("Use -h for help.");
14333                }
14334            } else if ("package".equals(cmd)) {
14335                String[] newArgs;
14336                if (opti >= args.length) {
14337                    pw.println("package: no package name specified");
14338                    pw.println("Use -h for help.");
14339                } else {
14340                    dumpPackage = args[opti];
14341                    opti++;
14342                    newArgs = new String[args.length - opti];
14343                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14344                            args.length - opti);
14345                    args = newArgs;
14346                    opti = 0;
14347                    more = true;
14348                }
14349            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14350                synchronized (this) {
14351                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14352                }
14353            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14354                if (dumpClient) {
14355                    ActiveServices.ServiceDumper dumper;
14356                    synchronized (this) {
14357                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14358                                dumpPackage);
14359                    }
14360                    dumper.dumpWithClient();
14361                } else {
14362                    synchronized (this) {
14363                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14364                                dumpPackage).dumpLocked();
14365                    }
14366                }
14367            } else if ("locks".equals(cmd)) {
14368                LockGuard.dump(fd, pw, args);
14369            } else {
14370                // Dumping a single activity?
14371                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14372                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14373                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14374                    if (res < 0) {
14375                        pw.println("Bad activity command, or no activities match: " + cmd);
14376                        pw.println("Use -h for help.");
14377                    }
14378                }
14379            }
14380            if (!more) {
14381                Binder.restoreCallingIdentity(origId);
14382                return;
14383            }
14384        }
14385
14386        // No piece of data specified, dump everything.
14387        if (dumpCheckinFormat) {
14388            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14389        } else if (dumpClient) {
14390            ActiveServices.ServiceDumper sdumper;
14391            synchronized (this) {
14392                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14393                pw.println();
14394                if (dumpAll) {
14395                    pw.println("-------------------------------------------------------------------------------");
14396                }
14397                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14398                pw.println();
14399                if (dumpAll) {
14400                    pw.println("-------------------------------------------------------------------------------");
14401                }
14402                if (dumpAll || dumpPackage != null) {
14403                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14404                    pw.println();
14405                    if (dumpAll) {
14406                        pw.println("-------------------------------------------------------------------------------");
14407                    }
14408                }
14409                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14410                pw.println();
14411                if (dumpAll) {
14412                    pw.println("-------------------------------------------------------------------------------");
14413                }
14414                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14415                pw.println();
14416                if (dumpAll) {
14417                    pw.println("-------------------------------------------------------------------------------");
14418                }
14419                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14420                        dumpPackage);
14421            }
14422            sdumper.dumpWithClient();
14423            pw.println();
14424            synchronized (this) {
14425                if (dumpAll) {
14426                    pw.println("-------------------------------------------------------------------------------");
14427                }
14428                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14429                pw.println();
14430                if (dumpAll) {
14431                    pw.println("-------------------------------------------------------------------------------");
14432                }
14433                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14434                if (mAssociations.size() > 0) {
14435                    pw.println();
14436                    if (dumpAll) {
14437                        pw.println("-------------------------------------------------------------------------------");
14438                    }
14439                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14440                }
14441                pw.println();
14442                if (dumpAll) {
14443                    pw.println("-------------------------------------------------------------------------------");
14444                }
14445                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14446            }
14447
14448        } else {
14449            synchronized (this) {
14450                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14451                pw.println();
14452                if (dumpAll) {
14453                    pw.println("-------------------------------------------------------------------------------");
14454                }
14455                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14456                pw.println();
14457                if (dumpAll) {
14458                    pw.println("-------------------------------------------------------------------------------");
14459                }
14460                if (dumpAll || dumpPackage != null) {
14461                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14462                    pw.println();
14463                    if (dumpAll) {
14464                        pw.println("-------------------------------------------------------------------------------");
14465                    }
14466                }
14467                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14468                pw.println();
14469                if (dumpAll) {
14470                    pw.println("-------------------------------------------------------------------------------");
14471                }
14472                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14473                pw.println();
14474                if (dumpAll) {
14475                    pw.println("-------------------------------------------------------------------------------");
14476                }
14477                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14478                        .dumpLocked();
14479                pw.println();
14480                if (dumpAll) {
14481                    pw.println("-------------------------------------------------------------------------------");
14482                }
14483                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14484                pw.println();
14485                if (dumpAll) {
14486                    pw.println("-------------------------------------------------------------------------------");
14487                }
14488                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14489                if (mAssociations.size() > 0) {
14490                    pw.println();
14491                    if (dumpAll) {
14492                        pw.println("-------------------------------------------------------------------------------");
14493                    }
14494                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14495                }
14496                pw.println();
14497                if (dumpAll) {
14498                    pw.println("-------------------------------------------------------------------------------");
14499                }
14500                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14501            }
14502        }
14503        Binder.restoreCallingIdentity(origId);
14504    }
14505
14506    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14507            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14508        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14509
14510        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14511                dumpPackage);
14512        boolean needSep = printedAnything;
14513
14514        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14515                dumpPackage, needSep, "  mFocusedActivity: ");
14516        if (printed) {
14517            printedAnything = true;
14518            needSep = false;
14519        }
14520
14521        if (dumpPackage == null) {
14522            if (needSep) {
14523                pw.println();
14524            }
14525            needSep = true;
14526            printedAnything = true;
14527            mStackSupervisor.dump(pw, "  ");
14528        }
14529
14530        if (!printedAnything) {
14531            pw.println("  (nothing)");
14532        }
14533    }
14534
14535    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14536            int opti, boolean dumpAll, String dumpPackage) {
14537        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14538
14539        boolean printedAnything = false;
14540
14541        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14542            boolean printedHeader = false;
14543
14544            final int N = mRecentTasks.size();
14545            for (int i=0; i<N; i++) {
14546                TaskRecord tr = mRecentTasks.get(i);
14547                if (dumpPackage != null) {
14548                    if (tr.realActivity == null ||
14549                            !dumpPackage.equals(tr.realActivity)) {
14550                        continue;
14551                    }
14552                }
14553                if (!printedHeader) {
14554                    pw.println("  Recent tasks:");
14555                    printedHeader = true;
14556                    printedAnything = true;
14557                }
14558                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14559                        pw.println(tr);
14560                if (dumpAll) {
14561                    mRecentTasks.get(i).dump(pw, "    ");
14562                }
14563            }
14564        }
14565
14566        if (!printedAnything) {
14567            pw.println("  (nothing)");
14568        }
14569    }
14570
14571    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14572            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14573        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14574
14575        int dumpUid = 0;
14576        if (dumpPackage != null) {
14577            IPackageManager pm = AppGlobals.getPackageManager();
14578            try {
14579                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14580            } catch (RemoteException e) {
14581            }
14582        }
14583
14584        boolean printedAnything = false;
14585
14586        final long now = SystemClock.uptimeMillis();
14587
14588        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14589            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14590                    = mAssociations.valueAt(i1);
14591            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14592                SparseArray<ArrayMap<String, Association>> sourceUids
14593                        = targetComponents.valueAt(i2);
14594                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14595                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14596                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14597                        Association ass = sourceProcesses.valueAt(i4);
14598                        if (dumpPackage != null) {
14599                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14600                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14601                                continue;
14602                            }
14603                        }
14604                        printedAnything = true;
14605                        pw.print("  ");
14606                        pw.print(ass.mTargetProcess);
14607                        pw.print("/");
14608                        UserHandle.formatUid(pw, ass.mTargetUid);
14609                        pw.print(" <- ");
14610                        pw.print(ass.mSourceProcess);
14611                        pw.print("/");
14612                        UserHandle.formatUid(pw, ass.mSourceUid);
14613                        pw.println();
14614                        pw.print("    via ");
14615                        pw.print(ass.mTargetComponent.flattenToShortString());
14616                        pw.println();
14617                        pw.print("    ");
14618                        long dur = ass.mTime;
14619                        if (ass.mNesting > 0) {
14620                            dur += now - ass.mStartTime;
14621                        }
14622                        TimeUtils.formatDuration(dur, pw);
14623                        pw.print(" (");
14624                        pw.print(ass.mCount);
14625                        pw.print(" times)");
14626                        pw.print("  ");
14627                        for (int i=0; i<ass.mStateTimes.length; i++) {
14628                            long amt = ass.mStateTimes[i];
14629                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14630                                amt += now - ass.mLastStateUptime;
14631                            }
14632                            if (amt != 0) {
14633                                pw.print(" ");
14634                                pw.print(ProcessList.makeProcStateString(
14635                                            i + ActivityManager.MIN_PROCESS_STATE));
14636                                pw.print("=");
14637                                TimeUtils.formatDuration(amt, pw);
14638                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14639                                    pw.print("*");
14640                                }
14641                            }
14642                        }
14643                        pw.println();
14644                        if (ass.mNesting > 0) {
14645                            pw.print("    Currently active: ");
14646                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14647                            pw.println();
14648                        }
14649                    }
14650                }
14651            }
14652
14653        }
14654
14655        if (!printedAnything) {
14656            pw.println("  (nothing)");
14657        }
14658    }
14659
14660    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14661            String header, boolean needSep) {
14662        boolean printed = false;
14663        int whichAppId = -1;
14664        if (dumpPackage != null) {
14665            try {
14666                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14667                        dumpPackage, 0);
14668                whichAppId = UserHandle.getAppId(info.uid);
14669            } catch (NameNotFoundException e) {
14670                e.printStackTrace();
14671            }
14672        }
14673        for (int i=0; i<uids.size(); i++) {
14674            UidRecord uidRec = uids.valueAt(i);
14675            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14676                continue;
14677            }
14678            if (!printed) {
14679                printed = true;
14680                if (needSep) {
14681                    pw.println();
14682                }
14683                pw.print("  ");
14684                pw.println(header);
14685                needSep = true;
14686            }
14687            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14688            pw.print(": "); pw.println(uidRec);
14689        }
14690        return printed;
14691    }
14692
14693    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14694            int opti, boolean dumpAll, String dumpPackage) {
14695        boolean needSep = false;
14696        boolean printedAnything = false;
14697        int numPers = 0;
14698
14699        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14700
14701        if (dumpAll) {
14702            final int NP = mProcessNames.getMap().size();
14703            for (int ip=0; ip<NP; ip++) {
14704                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14705                final int NA = procs.size();
14706                for (int ia=0; ia<NA; ia++) {
14707                    ProcessRecord r = procs.valueAt(ia);
14708                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14709                        continue;
14710                    }
14711                    if (!needSep) {
14712                        pw.println("  All known processes:");
14713                        needSep = true;
14714                        printedAnything = true;
14715                    }
14716                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14717                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14718                        pw.print(" "); pw.println(r);
14719                    r.dump(pw, "    ");
14720                    if (r.persistent) {
14721                        numPers++;
14722                    }
14723                }
14724            }
14725        }
14726
14727        if (mIsolatedProcesses.size() > 0) {
14728            boolean printed = false;
14729            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14730                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14731                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14732                    continue;
14733                }
14734                if (!printed) {
14735                    if (needSep) {
14736                        pw.println();
14737                    }
14738                    pw.println("  Isolated process list (sorted by uid):");
14739                    printedAnything = true;
14740                    printed = true;
14741                    needSep = true;
14742                }
14743                pw.println(String.format("%sIsolated #%2d: %s",
14744                        "    ", i, r.toString()));
14745            }
14746        }
14747
14748        if (mActiveUids.size() > 0) {
14749            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14750                printedAnything = needSep = true;
14751            }
14752        }
14753        if (mValidateUids.size() > 0) {
14754            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14755                printedAnything = needSep = true;
14756            }
14757        }
14758
14759        if (mLruProcesses.size() > 0) {
14760            if (needSep) {
14761                pw.println();
14762            }
14763            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14764                    pw.print(" total, non-act at ");
14765                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14766                    pw.print(", non-svc at ");
14767                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14768                    pw.println("):");
14769            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14770            needSep = true;
14771            printedAnything = true;
14772        }
14773
14774        if (dumpAll || dumpPackage != null) {
14775            synchronized (mPidsSelfLocked) {
14776                boolean printed = false;
14777                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14778                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14779                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14780                        continue;
14781                    }
14782                    if (!printed) {
14783                        if (needSep) pw.println();
14784                        needSep = true;
14785                        pw.println("  PID mappings:");
14786                        printed = true;
14787                        printedAnything = true;
14788                    }
14789                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14790                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14791                }
14792            }
14793        }
14794
14795        if (mForegroundProcesses.size() > 0) {
14796            synchronized (mPidsSelfLocked) {
14797                boolean printed = false;
14798                for (int i=0; i<mForegroundProcesses.size(); i++) {
14799                    ProcessRecord r = mPidsSelfLocked.get(
14800                            mForegroundProcesses.valueAt(i).pid);
14801                    if (dumpPackage != null && (r == null
14802                            || !r.pkgList.containsKey(dumpPackage))) {
14803                        continue;
14804                    }
14805                    if (!printed) {
14806                        if (needSep) pw.println();
14807                        needSep = true;
14808                        pw.println("  Foreground Processes:");
14809                        printed = true;
14810                        printedAnything = true;
14811                    }
14812                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14813                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14814                }
14815            }
14816        }
14817
14818        if (mPersistentStartingProcesses.size() > 0) {
14819            if (needSep) pw.println();
14820            needSep = true;
14821            printedAnything = true;
14822            pw.println("  Persisent processes that are starting:");
14823            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14824                    "Starting Norm", "Restarting PERS", dumpPackage);
14825        }
14826
14827        if (mRemovedProcesses.size() > 0) {
14828            if (needSep) pw.println();
14829            needSep = true;
14830            printedAnything = true;
14831            pw.println("  Processes that are being removed:");
14832            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14833                    "Removed Norm", "Removed PERS", dumpPackage);
14834        }
14835
14836        if (mProcessesOnHold.size() > 0) {
14837            if (needSep) pw.println();
14838            needSep = true;
14839            printedAnything = true;
14840            pw.println("  Processes that are on old until the system is ready:");
14841            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14842                    "OnHold Norm", "OnHold PERS", dumpPackage);
14843        }
14844
14845        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14846
14847        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14848        if (needSep) {
14849            printedAnything = true;
14850        }
14851
14852        if (dumpPackage == null) {
14853            pw.println();
14854            needSep = false;
14855            mUserController.dump(pw, dumpAll);
14856        }
14857        if (mHomeProcess != null && (dumpPackage == null
14858                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14859            if (needSep) {
14860                pw.println();
14861                needSep = false;
14862            }
14863            pw.println("  mHomeProcess: " + mHomeProcess);
14864        }
14865        if (mPreviousProcess != null && (dumpPackage == null
14866                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14867            if (needSep) {
14868                pw.println();
14869                needSep = false;
14870            }
14871            pw.println("  mPreviousProcess: " + mPreviousProcess);
14872        }
14873        if (dumpAll) {
14874            StringBuilder sb = new StringBuilder(128);
14875            sb.append("  mPreviousProcessVisibleTime: ");
14876            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14877            pw.println(sb);
14878        }
14879        if (mHeavyWeightProcess != null && (dumpPackage == null
14880                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14881            if (needSep) {
14882                pw.println();
14883                needSep = false;
14884            }
14885            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14886        }
14887        if (dumpPackage == null) {
14888            pw.println("  mConfiguration: " + mConfiguration);
14889        }
14890        if (dumpAll) {
14891            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14892            if (mCompatModePackages.getPackages().size() > 0) {
14893                boolean printed = false;
14894                for (Map.Entry<String, Integer> entry
14895                        : mCompatModePackages.getPackages().entrySet()) {
14896                    String pkg = entry.getKey();
14897                    int mode = entry.getValue();
14898                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14899                        continue;
14900                    }
14901                    if (!printed) {
14902                        pw.println("  mScreenCompatPackages:");
14903                        printed = true;
14904                    }
14905                    pw.print("    "); pw.print(pkg); pw.print(": ");
14906                            pw.print(mode); pw.println();
14907                }
14908            }
14909        }
14910        if (dumpPackage == null) {
14911            pw.println("  mWakefulness="
14912                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14913            pw.println("  mSleepTokens=" + mSleepTokens);
14914            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14915                    + lockScreenShownToString());
14916            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14917            if (mRunningVoice != null) {
14918                pw.println("  mRunningVoice=" + mRunningVoice);
14919                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14920            }
14921        }
14922        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14923                || mOrigWaitForDebugger) {
14924            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14925                    || dumpPackage.equals(mOrigDebugApp)) {
14926                if (needSep) {
14927                    pw.println();
14928                    needSep = false;
14929                }
14930                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14931                        + " mDebugTransient=" + mDebugTransient
14932                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14933            }
14934        }
14935        if (mCurAppTimeTracker != null) {
14936            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14937        }
14938        if (mMemWatchProcesses.getMap().size() > 0) {
14939            pw.println("  Mem watch processes:");
14940            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14941                    = mMemWatchProcesses.getMap();
14942            for (int i=0; i<procs.size(); i++) {
14943                final String proc = procs.keyAt(i);
14944                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14945                for (int j=0; j<uids.size(); j++) {
14946                    if (needSep) {
14947                        pw.println();
14948                        needSep = false;
14949                    }
14950                    StringBuilder sb = new StringBuilder();
14951                    sb.append("    ").append(proc).append('/');
14952                    UserHandle.formatUid(sb, uids.keyAt(j));
14953                    Pair<Long, String> val = uids.valueAt(j);
14954                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14955                    if (val.second != null) {
14956                        sb.append(", report to ").append(val.second);
14957                    }
14958                    pw.println(sb.toString());
14959                }
14960            }
14961            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14962            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14963            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14964                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14965        }
14966        if (mTrackAllocationApp != null) {
14967            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14968                if (needSep) {
14969                    pw.println();
14970                    needSep = false;
14971                }
14972                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14973            }
14974        }
14975        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14976                || mProfileFd != null) {
14977            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14978                if (needSep) {
14979                    pw.println();
14980                    needSep = false;
14981                }
14982                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14983                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14984                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14985                        + mAutoStopProfiler);
14986                pw.println("  mProfileType=" + mProfileType);
14987            }
14988        }
14989        if (mNativeDebuggingApp != null) {
14990            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14991                if (needSep) {
14992                    pw.println();
14993                    needSep = false;
14994                }
14995                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14996            }
14997        }
14998        if (dumpPackage == null) {
14999            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
15000                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
15001                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
15002            }
15003            if (mController != null) {
15004                pw.println("  mController=" + mController
15005                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15006            }
15007            if (dumpAll) {
15008                pw.println("  Total persistent processes: " + numPers);
15009                pw.println("  mProcessesReady=" + mProcessesReady
15010                        + " mSystemReady=" + mSystemReady
15011                        + " mBooted=" + mBooted
15012                        + " mFactoryTest=" + mFactoryTest);
15013                pw.println("  mBooting=" + mBooting
15014                        + " mCallFinishBooting=" + mCallFinishBooting
15015                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15016                pw.print("  mLastPowerCheckRealtime=");
15017                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15018                        pw.println("");
15019                pw.print("  mLastPowerCheckUptime=");
15020                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15021                        pw.println("");
15022                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15023                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15024                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15025                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15026                        + " (" + mLruProcesses.size() + " total)"
15027                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15028                        + " mNumServiceProcs=" + mNumServiceProcs
15029                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15030                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15031                        + " mLastMemoryLevel=" + mLastMemoryLevel
15032                        + " mLastNumProcesses=" + mLastNumProcesses);
15033                long now = SystemClock.uptimeMillis();
15034                pw.print("  mLastIdleTime=");
15035                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15036                        pw.print(" mLowRamSinceLastIdle=");
15037                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15038                        pw.println();
15039            }
15040        }
15041
15042        if (!printedAnything) {
15043            pw.println("  (nothing)");
15044        }
15045    }
15046
15047    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15048            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15049        if (mProcessesToGc.size() > 0) {
15050            boolean printed = false;
15051            long now = SystemClock.uptimeMillis();
15052            for (int i=0; i<mProcessesToGc.size(); i++) {
15053                ProcessRecord proc = mProcessesToGc.get(i);
15054                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15055                    continue;
15056                }
15057                if (!printed) {
15058                    if (needSep) pw.println();
15059                    needSep = true;
15060                    pw.println("  Processes that are waiting to GC:");
15061                    printed = true;
15062                }
15063                pw.print("    Process "); pw.println(proc);
15064                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15065                        pw.print(", last gced=");
15066                        pw.print(now-proc.lastRequestedGc);
15067                        pw.print(" ms ago, last lowMem=");
15068                        pw.print(now-proc.lastLowMemory);
15069                        pw.println(" ms ago");
15070
15071            }
15072        }
15073        return needSep;
15074    }
15075
15076    void printOomLevel(PrintWriter pw, String name, int adj) {
15077        pw.print("    ");
15078        if (adj >= 0) {
15079            pw.print(' ');
15080            if (adj < 10) pw.print(' ');
15081        } else {
15082            if (adj > -10) pw.print(' ');
15083        }
15084        pw.print(adj);
15085        pw.print(": ");
15086        pw.print(name);
15087        pw.print(" (");
15088        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15089        pw.println(")");
15090    }
15091
15092    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15093            int opti, boolean dumpAll) {
15094        boolean needSep = false;
15095
15096        if (mLruProcesses.size() > 0) {
15097            if (needSep) pw.println();
15098            needSep = true;
15099            pw.println("  OOM levels:");
15100            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15101            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15102            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15103            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15104            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15105            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15106            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15107            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15108            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15109            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15110            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15111            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15112            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15113            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15114
15115            if (needSep) pw.println();
15116            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15117                    pw.print(" total, non-act at ");
15118                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15119                    pw.print(", non-svc at ");
15120                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15121                    pw.println("):");
15122            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15123            needSep = true;
15124        }
15125
15126        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15127
15128        pw.println();
15129        pw.println("  mHomeProcess: " + mHomeProcess);
15130        pw.println("  mPreviousProcess: " + mPreviousProcess);
15131        if (mHeavyWeightProcess != null) {
15132            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15133        }
15134
15135        return true;
15136    }
15137
15138    /**
15139     * There are three ways to call this:
15140     *  - no provider specified: dump all the providers
15141     *  - a flattened component name that matched an existing provider was specified as the
15142     *    first arg: dump that one provider
15143     *  - the first arg isn't the flattened component name of an existing provider:
15144     *    dump all providers whose component contains the first arg as a substring
15145     */
15146    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15147            int opti, boolean dumpAll) {
15148        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15149    }
15150
15151    static class ItemMatcher {
15152        ArrayList<ComponentName> components;
15153        ArrayList<String> strings;
15154        ArrayList<Integer> objects;
15155        boolean all;
15156
15157        ItemMatcher() {
15158            all = true;
15159        }
15160
15161        void build(String name) {
15162            ComponentName componentName = ComponentName.unflattenFromString(name);
15163            if (componentName != null) {
15164                if (components == null) {
15165                    components = new ArrayList<ComponentName>();
15166                }
15167                components.add(componentName);
15168                all = false;
15169            } else {
15170                int objectId = 0;
15171                // Not a '/' separated full component name; maybe an object ID?
15172                try {
15173                    objectId = Integer.parseInt(name, 16);
15174                    if (objects == null) {
15175                        objects = new ArrayList<Integer>();
15176                    }
15177                    objects.add(objectId);
15178                    all = false;
15179                } catch (RuntimeException e) {
15180                    // Not an integer; just do string match.
15181                    if (strings == null) {
15182                        strings = new ArrayList<String>();
15183                    }
15184                    strings.add(name);
15185                    all = false;
15186                }
15187            }
15188        }
15189
15190        int build(String[] args, int opti) {
15191            for (; opti<args.length; opti++) {
15192                String name = args[opti];
15193                if ("--".equals(name)) {
15194                    return opti+1;
15195                }
15196                build(name);
15197            }
15198            return opti;
15199        }
15200
15201        boolean match(Object object, ComponentName comp) {
15202            if (all) {
15203                return true;
15204            }
15205            if (components != null) {
15206                for (int i=0; i<components.size(); i++) {
15207                    if (components.get(i).equals(comp)) {
15208                        return true;
15209                    }
15210                }
15211            }
15212            if (objects != null) {
15213                for (int i=0; i<objects.size(); i++) {
15214                    if (System.identityHashCode(object) == objects.get(i)) {
15215                        return true;
15216                    }
15217                }
15218            }
15219            if (strings != null) {
15220                String flat = comp.flattenToString();
15221                for (int i=0; i<strings.size(); i++) {
15222                    if (flat.contains(strings.get(i))) {
15223                        return true;
15224                    }
15225                }
15226            }
15227            return false;
15228        }
15229    }
15230
15231    /**
15232     * There are three things that cmd can be:
15233     *  - a flattened component name that matches an existing activity
15234     *  - the cmd arg isn't the flattened component name of an existing activity:
15235     *    dump all activity whose component contains the cmd as a substring
15236     *  - A hex number of the ActivityRecord object instance.
15237     */
15238    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15239            int opti, boolean dumpAll) {
15240        ArrayList<ActivityRecord> activities;
15241
15242        synchronized (this) {
15243            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15244        }
15245
15246        if (activities.size() <= 0) {
15247            return false;
15248        }
15249
15250        String[] newArgs = new String[args.length - opti];
15251        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15252
15253        TaskRecord lastTask = null;
15254        boolean needSep = false;
15255        for (int i=activities.size()-1; i>=0; i--) {
15256            ActivityRecord r = activities.get(i);
15257            if (needSep) {
15258                pw.println();
15259            }
15260            needSep = true;
15261            synchronized (this) {
15262                if (lastTask != r.task) {
15263                    lastTask = r.task;
15264                    pw.print("TASK "); pw.print(lastTask.affinity);
15265                            pw.print(" id="); pw.println(lastTask.taskId);
15266                    if (dumpAll) {
15267                        lastTask.dump(pw, "  ");
15268                    }
15269                }
15270            }
15271            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15272        }
15273        return true;
15274    }
15275
15276    /**
15277     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15278     * there is a thread associated with the activity.
15279     */
15280    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15281            final ActivityRecord r, String[] args, boolean dumpAll) {
15282        String innerPrefix = prefix + "  ";
15283        synchronized (this) {
15284            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15285                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15286                    pw.print(" pid=");
15287                    if (r.app != null) pw.println(r.app.pid);
15288                    else pw.println("(not running)");
15289            if (dumpAll) {
15290                r.dump(pw, innerPrefix);
15291            }
15292        }
15293        if (r.app != null && r.app.thread != null) {
15294            // flush anything that is already in the PrintWriter since the thread is going
15295            // to write to the file descriptor directly
15296            pw.flush();
15297            try {
15298                TransferPipe tp = new TransferPipe();
15299                try {
15300                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15301                            r.appToken, innerPrefix, args);
15302                    tp.go(fd);
15303                } finally {
15304                    tp.kill();
15305                }
15306            } catch (IOException e) {
15307                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15308            } catch (RemoteException e) {
15309                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15310            }
15311        }
15312    }
15313
15314    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15315            int opti, boolean dumpAll, String dumpPackage) {
15316        boolean needSep = false;
15317        boolean onlyHistory = false;
15318        boolean printedAnything = false;
15319
15320        if ("history".equals(dumpPackage)) {
15321            if (opti < args.length && "-s".equals(args[opti])) {
15322                dumpAll = false;
15323            }
15324            onlyHistory = true;
15325            dumpPackage = null;
15326        }
15327
15328        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15329        if (!onlyHistory && dumpAll) {
15330            if (mRegisteredReceivers.size() > 0) {
15331                boolean printed = false;
15332                Iterator it = mRegisteredReceivers.values().iterator();
15333                while (it.hasNext()) {
15334                    ReceiverList r = (ReceiverList)it.next();
15335                    if (dumpPackage != null && (r.app == null ||
15336                            !dumpPackage.equals(r.app.info.packageName))) {
15337                        continue;
15338                    }
15339                    if (!printed) {
15340                        pw.println("  Registered Receivers:");
15341                        needSep = true;
15342                        printed = true;
15343                        printedAnything = true;
15344                    }
15345                    pw.print("  * "); pw.println(r);
15346                    r.dump(pw, "    ");
15347                }
15348            }
15349
15350            if (mReceiverResolver.dump(pw, needSep ?
15351                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15352                    "    ", dumpPackage, false, false)) {
15353                needSep = true;
15354                printedAnything = true;
15355            }
15356        }
15357
15358        for (BroadcastQueue q : mBroadcastQueues) {
15359            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15360            printedAnything |= needSep;
15361        }
15362
15363        needSep = true;
15364
15365        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15366            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15367                if (needSep) {
15368                    pw.println();
15369                }
15370                needSep = true;
15371                printedAnything = true;
15372                pw.print("  Sticky broadcasts for user ");
15373                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15374                StringBuilder sb = new StringBuilder(128);
15375                for (Map.Entry<String, ArrayList<Intent>> ent
15376                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15377                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15378                    if (dumpAll) {
15379                        pw.println(":");
15380                        ArrayList<Intent> intents = ent.getValue();
15381                        final int N = intents.size();
15382                        for (int i=0; i<N; i++) {
15383                            sb.setLength(0);
15384                            sb.append("    Intent: ");
15385                            intents.get(i).toShortString(sb, false, true, false, false);
15386                            pw.println(sb.toString());
15387                            Bundle bundle = intents.get(i).getExtras();
15388                            if (bundle != null) {
15389                                pw.print("      ");
15390                                pw.println(bundle.toString());
15391                            }
15392                        }
15393                    } else {
15394                        pw.println("");
15395                    }
15396                }
15397            }
15398        }
15399
15400        if (!onlyHistory && dumpAll) {
15401            pw.println();
15402            for (BroadcastQueue queue : mBroadcastQueues) {
15403                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15404                        + queue.mBroadcastsScheduled);
15405            }
15406            pw.println("  mHandler:");
15407            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15408            needSep = true;
15409            printedAnything = true;
15410        }
15411
15412        if (!printedAnything) {
15413            pw.println("  (nothing)");
15414        }
15415    }
15416
15417    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15418            int opti, boolean dumpAll, String dumpPackage) {
15419        if (mCurBroadcastStats == null) {
15420            return;
15421        }
15422
15423        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15424        final long now = SystemClock.elapsedRealtime();
15425        if (mLastBroadcastStats != null) {
15426            pw.print("  Last stats (from ");
15427            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15428            pw.print(" to ");
15429            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15430            pw.print(", ");
15431            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15432                    - mLastBroadcastStats.mStartUptime, pw);
15433            pw.println(" uptime):");
15434            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15435                pw.println("    (nothing)");
15436            }
15437            pw.println();
15438        }
15439        pw.print("  Current stats (from ");
15440        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15441        pw.print(" to now, ");
15442        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15443                - mCurBroadcastStats.mStartUptime, pw);
15444        pw.println(" uptime):");
15445        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15446            pw.println("    (nothing)");
15447        }
15448    }
15449
15450    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15451            int opti, boolean fullCheckin, String dumpPackage) {
15452        if (mCurBroadcastStats == null) {
15453            return;
15454        }
15455
15456        if (mLastBroadcastStats != null) {
15457            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15458            if (fullCheckin) {
15459                mLastBroadcastStats = null;
15460                return;
15461            }
15462        }
15463        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15464        if (fullCheckin) {
15465            mCurBroadcastStats = null;
15466        }
15467    }
15468
15469    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15470            int opti, boolean dumpAll, String dumpPackage) {
15471        boolean needSep;
15472        boolean printedAnything = false;
15473
15474        ItemMatcher matcher = new ItemMatcher();
15475        matcher.build(args, opti);
15476
15477        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15478
15479        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15480        printedAnything |= needSep;
15481
15482        if (mLaunchingProviders.size() > 0) {
15483            boolean printed = false;
15484            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15485                ContentProviderRecord r = mLaunchingProviders.get(i);
15486                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15487                    continue;
15488                }
15489                if (!printed) {
15490                    if (needSep) pw.println();
15491                    needSep = true;
15492                    pw.println("  Launching content providers:");
15493                    printed = true;
15494                    printedAnything = true;
15495                }
15496                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15497                        pw.println(r);
15498            }
15499        }
15500
15501        if (!printedAnything) {
15502            pw.println("  (nothing)");
15503        }
15504    }
15505
15506    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15507            int opti, boolean dumpAll, String dumpPackage) {
15508        boolean needSep = false;
15509        boolean printedAnything = false;
15510
15511        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15512
15513        if (mGrantedUriPermissions.size() > 0) {
15514            boolean printed = false;
15515            int dumpUid = -2;
15516            if (dumpPackage != null) {
15517                try {
15518                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15519                            MATCH_UNINSTALLED_PACKAGES, 0);
15520                } catch (NameNotFoundException e) {
15521                    dumpUid = -1;
15522                }
15523            }
15524            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15525                int uid = mGrantedUriPermissions.keyAt(i);
15526                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15527                    continue;
15528                }
15529                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15530                if (!printed) {
15531                    if (needSep) pw.println();
15532                    needSep = true;
15533                    pw.println("  Granted Uri Permissions:");
15534                    printed = true;
15535                    printedAnything = true;
15536                }
15537                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15538                for (UriPermission perm : perms.values()) {
15539                    pw.print("    "); pw.println(perm);
15540                    if (dumpAll) {
15541                        perm.dump(pw, "      ");
15542                    }
15543                }
15544            }
15545        }
15546
15547        if (!printedAnything) {
15548            pw.println("  (nothing)");
15549        }
15550    }
15551
15552    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15553            int opti, boolean dumpAll, String dumpPackage) {
15554        boolean printed = false;
15555
15556        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15557
15558        if (mIntentSenderRecords.size() > 0) {
15559            Iterator<WeakReference<PendingIntentRecord>> it
15560                    = mIntentSenderRecords.values().iterator();
15561            while (it.hasNext()) {
15562                WeakReference<PendingIntentRecord> ref = it.next();
15563                PendingIntentRecord rec = ref != null ? ref.get(): null;
15564                if (dumpPackage != null && (rec == null
15565                        || !dumpPackage.equals(rec.key.packageName))) {
15566                    continue;
15567                }
15568                printed = true;
15569                if (rec != null) {
15570                    pw.print("  * "); pw.println(rec);
15571                    if (dumpAll) {
15572                        rec.dump(pw, "    ");
15573                    }
15574                } else {
15575                    pw.print("  * "); pw.println(ref);
15576                }
15577            }
15578        }
15579
15580        if (!printed) {
15581            pw.println("  (nothing)");
15582        }
15583    }
15584
15585    private static final int dumpProcessList(PrintWriter pw,
15586            ActivityManagerService service, List list,
15587            String prefix, String normalLabel, String persistentLabel,
15588            String dumpPackage) {
15589        int numPers = 0;
15590        final int N = list.size()-1;
15591        for (int i=N; i>=0; i--) {
15592            ProcessRecord r = (ProcessRecord)list.get(i);
15593            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15594                continue;
15595            }
15596            pw.println(String.format("%s%s #%2d: %s",
15597                    prefix, (r.persistent ? persistentLabel : normalLabel),
15598                    i, r.toString()));
15599            if (r.persistent) {
15600                numPers++;
15601            }
15602        }
15603        return numPers;
15604    }
15605
15606    private static final boolean dumpProcessOomList(PrintWriter pw,
15607            ActivityManagerService service, List<ProcessRecord> origList,
15608            String prefix, String normalLabel, String persistentLabel,
15609            boolean inclDetails, String dumpPackage) {
15610
15611        ArrayList<Pair<ProcessRecord, Integer>> list
15612                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15613        for (int i=0; i<origList.size(); i++) {
15614            ProcessRecord r = origList.get(i);
15615            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15616                continue;
15617            }
15618            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15619        }
15620
15621        if (list.size() <= 0) {
15622            return false;
15623        }
15624
15625        Comparator<Pair<ProcessRecord, Integer>> comparator
15626                = new Comparator<Pair<ProcessRecord, Integer>>() {
15627            @Override
15628            public int compare(Pair<ProcessRecord, Integer> object1,
15629                    Pair<ProcessRecord, Integer> object2) {
15630                if (object1.first.setAdj != object2.first.setAdj) {
15631                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15632                }
15633                if (object1.first.setProcState != object2.first.setProcState) {
15634                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15635                }
15636                if (object1.second.intValue() != object2.second.intValue()) {
15637                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15638                }
15639                return 0;
15640            }
15641        };
15642
15643        Collections.sort(list, comparator);
15644
15645        final long curRealtime = SystemClock.elapsedRealtime();
15646        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15647        final long curUptime = SystemClock.uptimeMillis();
15648        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15649
15650        for (int i=list.size()-1; i>=0; i--) {
15651            ProcessRecord r = list.get(i).first;
15652            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15653            char schedGroup;
15654            switch (r.setSchedGroup) {
15655                case ProcessList.SCHED_GROUP_BACKGROUND:
15656                    schedGroup = 'B';
15657                    break;
15658                case ProcessList.SCHED_GROUP_DEFAULT:
15659                    schedGroup = 'F';
15660                    break;
15661                case ProcessList.SCHED_GROUP_TOP_APP:
15662                    schedGroup = 'T';
15663                    break;
15664                default:
15665                    schedGroup = '?';
15666                    break;
15667            }
15668            char foreground;
15669            if (r.foregroundActivities) {
15670                foreground = 'A';
15671            } else if (r.foregroundServices) {
15672                foreground = 'S';
15673            } else {
15674                foreground = ' ';
15675            }
15676            String procState = ProcessList.makeProcStateString(r.curProcState);
15677            pw.print(prefix);
15678            pw.print(r.persistent ? persistentLabel : normalLabel);
15679            pw.print(" #");
15680            int num = (origList.size()-1)-list.get(i).second;
15681            if (num < 10) pw.print(' ');
15682            pw.print(num);
15683            pw.print(": ");
15684            pw.print(oomAdj);
15685            pw.print(' ');
15686            pw.print(schedGroup);
15687            pw.print('/');
15688            pw.print(foreground);
15689            pw.print('/');
15690            pw.print(procState);
15691            pw.print(" trm:");
15692            if (r.trimMemoryLevel < 10) pw.print(' ');
15693            pw.print(r.trimMemoryLevel);
15694            pw.print(' ');
15695            pw.print(r.toShortString());
15696            pw.print(" (");
15697            pw.print(r.adjType);
15698            pw.println(')');
15699            if (r.adjSource != null || r.adjTarget != null) {
15700                pw.print(prefix);
15701                pw.print("    ");
15702                if (r.adjTarget instanceof ComponentName) {
15703                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15704                } else if (r.adjTarget != null) {
15705                    pw.print(r.adjTarget.toString());
15706                } else {
15707                    pw.print("{null}");
15708                }
15709                pw.print("<=");
15710                if (r.adjSource instanceof ProcessRecord) {
15711                    pw.print("Proc{");
15712                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15713                    pw.println("}");
15714                } else if (r.adjSource != null) {
15715                    pw.println(r.adjSource.toString());
15716                } else {
15717                    pw.println("{null}");
15718                }
15719            }
15720            if (inclDetails) {
15721                pw.print(prefix);
15722                pw.print("    ");
15723                pw.print("oom: max="); pw.print(r.maxAdj);
15724                pw.print(" curRaw="); pw.print(r.curRawAdj);
15725                pw.print(" setRaw="); pw.print(r.setRawAdj);
15726                pw.print(" cur="); pw.print(r.curAdj);
15727                pw.print(" set="); pw.println(r.setAdj);
15728                pw.print(prefix);
15729                pw.print("    ");
15730                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15731                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15732                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15733                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15734                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15735                pw.println();
15736                pw.print(prefix);
15737                pw.print("    ");
15738                pw.print("cached="); pw.print(r.cached);
15739                pw.print(" empty="); pw.print(r.empty);
15740                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15741
15742                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15743                    if (r.lastWakeTime != 0) {
15744                        long wtime;
15745                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15746                        synchronized (stats) {
15747                            wtime = stats.getProcessWakeTime(r.info.uid,
15748                                    r.pid, curRealtime);
15749                        }
15750                        long timeUsed = wtime - r.lastWakeTime;
15751                        pw.print(prefix);
15752                        pw.print("    ");
15753                        pw.print("keep awake over ");
15754                        TimeUtils.formatDuration(realtimeSince, pw);
15755                        pw.print(" used ");
15756                        TimeUtils.formatDuration(timeUsed, pw);
15757                        pw.print(" (");
15758                        pw.print((timeUsed*100)/realtimeSince);
15759                        pw.println("%)");
15760                    }
15761                    if (r.lastCpuTime != 0) {
15762                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15763                        pw.print(prefix);
15764                        pw.print("    ");
15765                        pw.print("run cpu over ");
15766                        TimeUtils.formatDuration(uptimeSince, pw);
15767                        pw.print(" used ");
15768                        TimeUtils.formatDuration(timeUsed, pw);
15769                        pw.print(" (");
15770                        pw.print((timeUsed*100)/uptimeSince);
15771                        pw.println("%)");
15772                    }
15773                }
15774            }
15775        }
15776        return true;
15777    }
15778
15779    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15780            String[] args) {
15781        ArrayList<ProcessRecord> procs;
15782        synchronized (this) {
15783            if (args != null && args.length > start
15784                    && args[start].charAt(0) != '-') {
15785                procs = new ArrayList<ProcessRecord>();
15786                int pid = -1;
15787                try {
15788                    pid = Integer.parseInt(args[start]);
15789                } catch (NumberFormatException e) {
15790                }
15791                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15792                    ProcessRecord proc = mLruProcesses.get(i);
15793                    if (proc.pid == pid) {
15794                        procs.add(proc);
15795                    } else if (allPkgs && proc.pkgList != null
15796                            && proc.pkgList.containsKey(args[start])) {
15797                        procs.add(proc);
15798                    } else if (proc.processName.equals(args[start])) {
15799                        procs.add(proc);
15800                    }
15801                }
15802                if (procs.size() <= 0) {
15803                    return null;
15804                }
15805            } else {
15806                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15807            }
15808        }
15809        return procs;
15810    }
15811
15812    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15813            PrintWriter pw, String[] args) {
15814        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15815        if (procs == null) {
15816            pw.println("No process found for: " + args[0]);
15817            return;
15818        }
15819
15820        long uptime = SystemClock.uptimeMillis();
15821        long realtime = SystemClock.elapsedRealtime();
15822        pw.println("Applications Graphics Acceleration Info:");
15823        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15824
15825        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15826            ProcessRecord r = procs.get(i);
15827            if (r.thread != null) {
15828                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15829                pw.flush();
15830                try {
15831                    TransferPipe tp = new TransferPipe();
15832                    try {
15833                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15834                        tp.go(fd);
15835                    } finally {
15836                        tp.kill();
15837                    }
15838                } catch (IOException e) {
15839                    pw.println("Failure while dumping the app: " + r);
15840                    pw.flush();
15841                } catch (RemoteException e) {
15842                    pw.println("Got a RemoteException while dumping the app " + r);
15843                    pw.flush();
15844                }
15845            }
15846        }
15847    }
15848
15849    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15850        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15851        if (procs == null) {
15852            pw.println("No process found for: " + args[0]);
15853            return;
15854        }
15855
15856        pw.println("Applications Database Info:");
15857
15858        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15859            ProcessRecord r = procs.get(i);
15860            if (r.thread != null) {
15861                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15862                pw.flush();
15863                try {
15864                    TransferPipe tp = new TransferPipe();
15865                    try {
15866                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15867                        tp.go(fd);
15868                    } finally {
15869                        tp.kill();
15870                    }
15871                } catch (IOException e) {
15872                    pw.println("Failure while dumping the app: " + r);
15873                    pw.flush();
15874                } catch (RemoteException e) {
15875                    pw.println("Got a RemoteException while dumping the app " + r);
15876                    pw.flush();
15877                }
15878            }
15879        }
15880    }
15881
15882    final static class MemItem {
15883        final boolean isProc;
15884        final String label;
15885        final String shortLabel;
15886        final long pss;
15887        final long swapPss;
15888        final int id;
15889        final boolean hasActivities;
15890        ArrayList<MemItem> subitems;
15891
15892        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15893                boolean _hasActivities) {
15894            isProc = true;
15895            label = _label;
15896            shortLabel = _shortLabel;
15897            pss = _pss;
15898            swapPss = _swapPss;
15899            id = _id;
15900            hasActivities = _hasActivities;
15901        }
15902
15903        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15904            isProc = false;
15905            label = _label;
15906            shortLabel = _shortLabel;
15907            pss = _pss;
15908            swapPss = _swapPss;
15909            id = _id;
15910            hasActivities = false;
15911        }
15912    }
15913
15914    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15915            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15916        if (sort && !isCompact) {
15917            Collections.sort(items, new Comparator<MemItem>() {
15918                @Override
15919                public int compare(MemItem lhs, MemItem rhs) {
15920                    if (lhs.pss < rhs.pss) {
15921                        return 1;
15922                    } else if (lhs.pss > rhs.pss) {
15923                        return -1;
15924                    }
15925                    return 0;
15926                }
15927            });
15928        }
15929
15930        for (int i=0; i<items.size(); i++) {
15931            MemItem mi = items.get(i);
15932            if (!isCompact) {
15933                if (dumpSwapPss) {
15934                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15935                            mi.label, stringifyKBSize(mi.swapPss));
15936                } else {
15937                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15938                }
15939            } else if (mi.isProc) {
15940                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15941                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15942                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15943                pw.println(mi.hasActivities ? ",a" : ",e");
15944            } else {
15945                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15946                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15947            }
15948            if (mi.subitems != null) {
15949                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15950                        true, isCompact, dumpSwapPss);
15951            }
15952        }
15953    }
15954
15955    // These are in KB.
15956    static final long[] DUMP_MEM_BUCKETS = new long[] {
15957        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15958        120*1024, 160*1024, 200*1024,
15959        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15960        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15961    };
15962
15963    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15964            boolean stackLike) {
15965        int start = label.lastIndexOf('.');
15966        if (start >= 0) start++;
15967        else start = 0;
15968        int end = label.length();
15969        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15970            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15971                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15972                out.append(bucket);
15973                out.append(stackLike ? "MB." : "MB ");
15974                out.append(label, start, end);
15975                return;
15976            }
15977        }
15978        out.append(memKB/1024);
15979        out.append(stackLike ? "MB." : "MB ");
15980        out.append(label, start, end);
15981    }
15982
15983    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15984            ProcessList.NATIVE_ADJ,
15985            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15986            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15987            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15988            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15989            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15990            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15991    };
15992    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15993            "Native",
15994            "System", "Persistent", "Persistent Service", "Foreground",
15995            "Visible", "Perceptible",
15996            "Heavy Weight", "Backup",
15997            "A Services", "Home",
15998            "Previous", "B Services", "Cached"
15999    };
16000    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16001            "native",
16002            "sys", "pers", "persvc", "fore",
16003            "vis", "percept",
16004            "heavy", "backup",
16005            "servicea", "home",
16006            "prev", "serviceb", "cached"
16007    };
16008
16009    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16010            long realtime, boolean isCheckinRequest, boolean isCompact) {
16011        if (isCompact) {
16012            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16013        }
16014        if (isCheckinRequest || isCompact) {
16015            // short checkin version
16016            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16017        } else {
16018            pw.println("Applications Memory Usage (in Kilobytes):");
16019            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16020        }
16021    }
16022
16023    private static final int KSM_SHARED = 0;
16024    private static final int KSM_SHARING = 1;
16025    private static final int KSM_UNSHARED = 2;
16026    private static final int KSM_VOLATILE = 3;
16027
16028    private final long[] getKsmInfo() {
16029        long[] longOut = new long[4];
16030        final int[] SINGLE_LONG_FORMAT = new int[] {
16031            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16032        };
16033        long[] longTmp = new long[1];
16034        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16035                SINGLE_LONG_FORMAT, null, longTmp, null);
16036        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16037        longTmp[0] = 0;
16038        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16039                SINGLE_LONG_FORMAT, null, longTmp, null);
16040        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16041        longTmp[0] = 0;
16042        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16043                SINGLE_LONG_FORMAT, null, longTmp, null);
16044        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16045        longTmp[0] = 0;
16046        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16047                SINGLE_LONG_FORMAT, null, longTmp, null);
16048        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16049        return longOut;
16050    }
16051
16052    private static String stringifySize(long size, int order) {
16053        Locale locale = Locale.US;
16054        switch (order) {
16055            case 1:
16056                return String.format(locale, "%,13d", size);
16057            case 1024:
16058                return String.format(locale, "%,9dK", size / 1024);
16059            case 1024 * 1024:
16060                return String.format(locale, "%,5dM", size / 1024 / 1024);
16061            case 1024 * 1024 * 1024:
16062                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16063            default:
16064                throw new IllegalArgumentException("Invalid size order");
16065        }
16066    }
16067
16068    private static String stringifyKBSize(long size) {
16069        return stringifySize(size * 1024, 1024);
16070    }
16071
16072    // Update this version number in case you change the 'compact' format
16073    private static final int MEMINFO_COMPACT_VERSION = 1;
16074
16075    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16076            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16077        boolean dumpDetails = false;
16078        boolean dumpFullDetails = false;
16079        boolean dumpDalvik = false;
16080        boolean dumpSummaryOnly = false;
16081        boolean dumpUnreachable = false;
16082        boolean oomOnly = false;
16083        boolean isCompact = false;
16084        boolean localOnly = false;
16085        boolean packages = false;
16086        boolean isCheckinRequest = false;
16087        boolean dumpSwapPss = false;
16088
16089        int opti = 0;
16090        while (opti < args.length) {
16091            String opt = args[opti];
16092            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16093                break;
16094            }
16095            opti++;
16096            if ("-a".equals(opt)) {
16097                dumpDetails = true;
16098                dumpFullDetails = true;
16099                dumpDalvik = true;
16100                dumpSwapPss = true;
16101            } else if ("-d".equals(opt)) {
16102                dumpDalvik = true;
16103            } else if ("-c".equals(opt)) {
16104                isCompact = true;
16105            } else if ("-s".equals(opt)) {
16106                dumpDetails = true;
16107                dumpSummaryOnly = true;
16108            } else if ("-S".equals(opt)) {
16109                dumpSwapPss = true;
16110            } else if ("--unreachable".equals(opt)) {
16111                dumpUnreachable = true;
16112            } else if ("--oom".equals(opt)) {
16113                oomOnly = true;
16114            } else if ("--local".equals(opt)) {
16115                localOnly = true;
16116            } else if ("--package".equals(opt)) {
16117                packages = true;
16118            } else if ("--checkin".equals(opt)) {
16119                isCheckinRequest = true;
16120
16121            } else if ("-h".equals(opt)) {
16122                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16123                pw.println("  -a: include all available information for each process.");
16124                pw.println("  -d: include dalvik details.");
16125                pw.println("  -c: dump in a compact machine-parseable representation.");
16126                pw.println("  -s: dump only summary of application memory usage.");
16127                pw.println("  -S: dump also SwapPss.");
16128                pw.println("  --oom: only show processes organized by oom adj.");
16129                pw.println("  --local: only collect details locally, don't call process.");
16130                pw.println("  --package: interpret process arg as package, dumping all");
16131                pw.println("             processes that have loaded that package.");
16132                pw.println("  --checkin: dump data for a checkin");
16133                pw.println("If [process] is specified it can be the name or ");
16134                pw.println("pid of a specific process to dump.");
16135                return;
16136            } else {
16137                pw.println("Unknown argument: " + opt + "; use -h for help");
16138            }
16139        }
16140
16141        long uptime = SystemClock.uptimeMillis();
16142        long realtime = SystemClock.elapsedRealtime();
16143        final long[] tmpLong = new long[1];
16144
16145        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16146        if (procs == null) {
16147            // No Java processes.  Maybe they want to print a native process.
16148            if (args != null && args.length > opti
16149                    && args[opti].charAt(0) != '-') {
16150                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16151                        = new ArrayList<ProcessCpuTracker.Stats>();
16152                updateCpuStatsNow();
16153                int findPid = -1;
16154                try {
16155                    findPid = Integer.parseInt(args[opti]);
16156                } catch (NumberFormatException e) {
16157                }
16158                synchronized (mProcessCpuTracker) {
16159                    final int N = mProcessCpuTracker.countStats();
16160                    for (int i=0; i<N; i++) {
16161                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16162                        if (st.pid == findPid || (st.baseName != null
16163                                && st.baseName.equals(args[opti]))) {
16164                            nativeProcs.add(st);
16165                        }
16166                    }
16167                }
16168                if (nativeProcs.size() > 0) {
16169                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16170                            isCompact);
16171                    Debug.MemoryInfo mi = null;
16172                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16173                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16174                        final int pid = r.pid;
16175                        if (!isCheckinRequest && dumpDetails) {
16176                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16177                        }
16178                        if (mi == null) {
16179                            mi = new Debug.MemoryInfo();
16180                        }
16181                        if (dumpDetails || (!brief && !oomOnly)) {
16182                            Debug.getMemoryInfo(pid, mi);
16183                        } else {
16184                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16185                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16186                        }
16187                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16188                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16189                        if (isCheckinRequest) {
16190                            pw.println();
16191                        }
16192                    }
16193                    return;
16194                }
16195            }
16196            pw.println("No process found for: " + args[opti]);
16197            return;
16198        }
16199
16200        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16201            dumpDetails = true;
16202        }
16203
16204        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16205
16206        String[] innerArgs = new String[args.length-opti];
16207        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16208
16209        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16210        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16211        long nativePss = 0;
16212        long nativeSwapPss = 0;
16213        long dalvikPss = 0;
16214        long dalvikSwapPss = 0;
16215        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16216                EmptyArray.LONG;
16217        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16218                EmptyArray.LONG;
16219        long otherPss = 0;
16220        long otherSwapPss = 0;
16221        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16222        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16223
16224        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16225        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16226        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16227                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16228
16229        long totalPss = 0;
16230        long totalSwapPss = 0;
16231        long cachedPss = 0;
16232        long cachedSwapPss = 0;
16233        boolean hasSwapPss = false;
16234
16235        Debug.MemoryInfo mi = null;
16236        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16237            final ProcessRecord r = procs.get(i);
16238            final IApplicationThread thread;
16239            final int pid;
16240            final int oomAdj;
16241            final boolean hasActivities;
16242            synchronized (this) {
16243                thread = r.thread;
16244                pid = r.pid;
16245                oomAdj = r.getSetAdjWithServices();
16246                hasActivities = r.activities.size() > 0;
16247            }
16248            if (thread != null) {
16249                if (!isCheckinRequest && dumpDetails) {
16250                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16251                }
16252                if (mi == null) {
16253                    mi = new Debug.MemoryInfo();
16254                }
16255                if (dumpDetails || (!brief && !oomOnly)) {
16256                    Debug.getMemoryInfo(pid, mi);
16257                    hasSwapPss = mi.hasSwappedOutPss;
16258                } else {
16259                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16260                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16261                }
16262                if (dumpDetails) {
16263                    if (localOnly) {
16264                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16265                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16266                        if (isCheckinRequest) {
16267                            pw.println();
16268                        }
16269                    } else {
16270                        try {
16271                            pw.flush();
16272                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16273                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16274                        } catch (RemoteException e) {
16275                            if (!isCheckinRequest) {
16276                                pw.println("Got RemoteException!");
16277                                pw.flush();
16278                            }
16279                        }
16280                    }
16281                }
16282
16283                final long myTotalPss = mi.getTotalPss();
16284                final long myTotalUss = mi.getTotalUss();
16285                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16286
16287                synchronized (this) {
16288                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16289                        // Record this for posterity if the process has been stable.
16290                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16291                    }
16292                }
16293
16294                if (!isCheckinRequest && mi != null) {
16295                    totalPss += myTotalPss;
16296                    totalSwapPss += myTotalSwapPss;
16297                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16298                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16299                            myTotalSwapPss, pid, hasActivities);
16300                    procMems.add(pssItem);
16301                    procMemsMap.put(pid, pssItem);
16302
16303                    nativePss += mi.nativePss;
16304                    nativeSwapPss += mi.nativeSwappedOutPss;
16305                    dalvikPss += mi.dalvikPss;
16306                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16307                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16308                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16309                        dalvikSubitemSwapPss[j] +=
16310                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16311                    }
16312                    otherPss += mi.otherPss;
16313                    otherSwapPss += mi.otherSwappedOutPss;
16314                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16315                        long mem = mi.getOtherPss(j);
16316                        miscPss[j] += mem;
16317                        otherPss -= mem;
16318                        mem = mi.getOtherSwappedOutPss(j);
16319                        miscSwapPss[j] += mem;
16320                        otherSwapPss -= mem;
16321                    }
16322
16323                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16324                        cachedPss += myTotalPss;
16325                        cachedSwapPss += myTotalSwapPss;
16326                    }
16327
16328                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16329                        if (oomIndex == (oomPss.length - 1)
16330                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16331                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16332                            oomPss[oomIndex] += myTotalPss;
16333                            oomSwapPss[oomIndex] += myTotalSwapPss;
16334                            if (oomProcs[oomIndex] == null) {
16335                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16336                            }
16337                            oomProcs[oomIndex].add(pssItem);
16338                            break;
16339                        }
16340                    }
16341                }
16342            }
16343        }
16344
16345        long nativeProcTotalPss = 0;
16346
16347        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16348            // If we are showing aggregations, also look for native processes to
16349            // include so that our aggregations are more accurate.
16350            updateCpuStatsNow();
16351            mi = null;
16352            synchronized (mProcessCpuTracker) {
16353                final int N = mProcessCpuTracker.countStats();
16354                for (int i=0; i<N; i++) {
16355                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16356                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16357                        if (mi == null) {
16358                            mi = new Debug.MemoryInfo();
16359                        }
16360                        if (!brief && !oomOnly) {
16361                            Debug.getMemoryInfo(st.pid, mi);
16362                        } else {
16363                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16364                            mi.nativePrivateDirty = (int)tmpLong[0];
16365                        }
16366
16367                        final long myTotalPss = mi.getTotalPss();
16368                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16369                        totalPss += myTotalPss;
16370                        nativeProcTotalPss += myTotalPss;
16371
16372                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16373                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16374                        procMems.add(pssItem);
16375
16376                        nativePss += mi.nativePss;
16377                        nativeSwapPss += mi.nativeSwappedOutPss;
16378                        dalvikPss += mi.dalvikPss;
16379                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16380                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16381                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16382                            dalvikSubitemSwapPss[j] +=
16383                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16384                        }
16385                        otherPss += mi.otherPss;
16386                        otherSwapPss += mi.otherSwappedOutPss;
16387                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16388                            long mem = mi.getOtherPss(j);
16389                            miscPss[j] += mem;
16390                            otherPss -= mem;
16391                            mem = mi.getOtherSwappedOutPss(j);
16392                            miscSwapPss[j] += mem;
16393                            otherSwapPss -= mem;
16394                        }
16395                        oomPss[0] += myTotalPss;
16396                        oomSwapPss[0] += myTotalSwapPss;
16397                        if (oomProcs[0] == null) {
16398                            oomProcs[0] = new ArrayList<MemItem>();
16399                        }
16400                        oomProcs[0].add(pssItem);
16401                    }
16402                }
16403            }
16404
16405            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16406
16407            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16408            final MemItem dalvikItem =
16409                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16410            if (dalvikSubitemPss.length > 0) {
16411                dalvikItem.subitems = new ArrayList<MemItem>();
16412                for (int j=0; j<dalvikSubitemPss.length; j++) {
16413                    final String name = Debug.MemoryInfo.getOtherLabel(
16414                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16415                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16416                                    dalvikSubitemSwapPss[j], j));
16417                }
16418            }
16419            catMems.add(dalvikItem);
16420            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16421            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16422                String label = Debug.MemoryInfo.getOtherLabel(j);
16423                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16424            }
16425
16426            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16427            for (int j=0; j<oomPss.length; j++) {
16428                if (oomPss[j] != 0) {
16429                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16430                            : DUMP_MEM_OOM_LABEL[j];
16431                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16432                            DUMP_MEM_OOM_ADJ[j]);
16433                    item.subitems = oomProcs[j];
16434                    oomMems.add(item);
16435                }
16436            }
16437
16438            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16439            if (!brief && !oomOnly && !isCompact) {
16440                pw.println();
16441                pw.println("Total PSS by process:");
16442                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16443                pw.println();
16444            }
16445            if (!isCompact) {
16446                pw.println("Total PSS by OOM adjustment:");
16447            }
16448            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16449            if (!brief && !oomOnly) {
16450                PrintWriter out = categoryPw != null ? categoryPw : pw;
16451                if (!isCompact) {
16452                    out.println();
16453                    out.println("Total PSS by category:");
16454                }
16455                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16456            }
16457            if (!isCompact) {
16458                pw.println();
16459            }
16460            MemInfoReader memInfo = new MemInfoReader();
16461            memInfo.readMemInfo();
16462            if (nativeProcTotalPss > 0) {
16463                synchronized (this) {
16464                    final long cachedKb = memInfo.getCachedSizeKb();
16465                    final long freeKb = memInfo.getFreeSizeKb();
16466                    final long zramKb = memInfo.getZramTotalSizeKb();
16467                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16468                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16469                            kernelKb*1024, nativeProcTotalPss*1024);
16470                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16471                            nativeProcTotalPss);
16472                }
16473            }
16474            if (!brief) {
16475                if (!isCompact) {
16476                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16477                    pw.print(" (status ");
16478                    switch (mLastMemoryLevel) {
16479                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16480                            pw.println("normal)");
16481                            break;
16482                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16483                            pw.println("moderate)");
16484                            break;
16485                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16486                            pw.println("low)");
16487                            break;
16488                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16489                            pw.println("critical)");
16490                            break;
16491                        default:
16492                            pw.print(mLastMemoryLevel);
16493                            pw.println(")");
16494                            break;
16495                    }
16496                    pw.print(" Free RAM: ");
16497                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16498                            + memInfo.getFreeSizeKb()));
16499                    pw.print(" (");
16500                    pw.print(stringifyKBSize(cachedPss));
16501                    pw.print(" cached pss + ");
16502                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16503                    pw.print(" cached kernel + ");
16504                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16505                    pw.println(" free)");
16506                } else {
16507                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16508                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16509                            + memInfo.getFreeSizeKb()); pw.print(",");
16510                    pw.println(totalPss - cachedPss);
16511                }
16512            }
16513            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16514                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16515                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16516            if (!isCompact) {
16517                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16518                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16519                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16520                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16521                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16522            } else {
16523                pw.print("lostram,"); pw.println(lostRAM);
16524            }
16525            if (!brief) {
16526                if (memInfo.getZramTotalSizeKb() != 0) {
16527                    if (!isCompact) {
16528                        pw.print("     ZRAM: ");
16529                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16530                                pw.print(" physical used for ");
16531                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16532                                        - memInfo.getSwapFreeSizeKb()));
16533                                pw.print(" in swap (");
16534                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16535                                pw.println(" total swap)");
16536                    } else {
16537                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16538                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16539                                pw.println(memInfo.getSwapFreeSizeKb());
16540                    }
16541                }
16542                final long[] ksm = getKsmInfo();
16543                if (!isCompact) {
16544                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16545                            || ksm[KSM_VOLATILE] != 0) {
16546                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16547                                pw.print(" saved from shared ");
16548                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16549                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16550                                pw.print(" unshared; ");
16551                                pw.print(stringifyKBSize(
16552                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16553                    }
16554                    pw.print("   Tuning: ");
16555                    pw.print(ActivityManager.staticGetMemoryClass());
16556                    pw.print(" (large ");
16557                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16558                    pw.print("), oom ");
16559                    pw.print(stringifySize(
16560                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16561                    pw.print(", restore limit ");
16562                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16563                    if (ActivityManager.isLowRamDeviceStatic()) {
16564                        pw.print(" (low-ram)");
16565                    }
16566                    if (ActivityManager.isHighEndGfx()) {
16567                        pw.print(" (high-end-gfx)");
16568                    }
16569                    pw.println();
16570                } else {
16571                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16572                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16573                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16574                    pw.print("tuning,");
16575                    pw.print(ActivityManager.staticGetMemoryClass());
16576                    pw.print(',');
16577                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16578                    pw.print(',');
16579                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16580                    if (ActivityManager.isLowRamDeviceStatic()) {
16581                        pw.print(",low-ram");
16582                    }
16583                    if (ActivityManager.isHighEndGfx()) {
16584                        pw.print(",high-end-gfx");
16585                    }
16586                    pw.println();
16587                }
16588            }
16589        }
16590    }
16591
16592    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16593            long memtrack, String name) {
16594        sb.append("  ");
16595        sb.append(ProcessList.makeOomAdjString(oomAdj));
16596        sb.append(' ');
16597        sb.append(ProcessList.makeProcStateString(procState));
16598        sb.append(' ');
16599        ProcessList.appendRamKb(sb, pss);
16600        sb.append(": ");
16601        sb.append(name);
16602        if (memtrack > 0) {
16603            sb.append(" (");
16604            sb.append(stringifyKBSize(memtrack));
16605            sb.append(" memtrack)");
16606        }
16607    }
16608
16609    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16610        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16611        sb.append(" (pid ");
16612        sb.append(mi.pid);
16613        sb.append(") ");
16614        sb.append(mi.adjType);
16615        sb.append('\n');
16616        if (mi.adjReason != null) {
16617            sb.append("                      ");
16618            sb.append(mi.adjReason);
16619            sb.append('\n');
16620        }
16621    }
16622
16623    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16624        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16625        for (int i=0, N=memInfos.size(); i<N; i++) {
16626            ProcessMemInfo mi = memInfos.get(i);
16627            infoMap.put(mi.pid, mi);
16628        }
16629        updateCpuStatsNow();
16630        long[] memtrackTmp = new long[1];
16631        final List<ProcessCpuTracker.Stats> stats;
16632        // Get a list of Stats that have vsize > 0
16633        synchronized (mProcessCpuTracker) {
16634            stats = mProcessCpuTracker.getStats((st) -> {
16635                return st.vsize > 0;
16636            });
16637        }
16638        final int statsCount = stats.size();
16639        for (int i = 0; i < statsCount; i++) {
16640            ProcessCpuTracker.Stats st = stats.get(i);
16641            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16642            if (pss > 0) {
16643                if (infoMap.indexOfKey(st.pid) < 0) {
16644                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16645                            ProcessList.NATIVE_ADJ, -1, "native", null);
16646                    mi.pss = pss;
16647                    mi.memtrack = memtrackTmp[0];
16648                    memInfos.add(mi);
16649                }
16650            }
16651        }
16652
16653        long totalPss = 0;
16654        long totalMemtrack = 0;
16655        for (int i=0, N=memInfos.size(); i<N; i++) {
16656            ProcessMemInfo mi = memInfos.get(i);
16657            if (mi.pss == 0) {
16658                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16659                mi.memtrack = memtrackTmp[0];
16660            }
16661            totalPss += mi.pss;
16662            totalMemtrack += mi.memtrack;
16663        }
16664        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16665            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16666                if (lhs.oomAdj != rhs.oomAdj) {
16667                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16668                }
16669                if (lhs.pss != rhs.pss) {
16670                    return lhs.pss < rhs.pss ? 1 : -1;
16671                }
16672                return 0;
16673            }
16674        });
16675
16676        StringBuilder tag = new StringBuilder(128);
16677        StringBuilder stack = new StringBuilder(128);
16678        tag.append("Low on memory -- ");
16679        appendMemBucket(tag, totalPss, "total", false);
16680        appendMemBucket(stack, totalPss, "total", true);
16681
16682        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16683        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16684        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16685
16686        boolean firstLine = true;
16687        int lastOomAdj = Integer.MIN_VALUE;
16688        long extraNativeRam = 0;
16689        long extraNativeMemtrack = 0;
16690        long cachedPss = 0;
16691        for (int i=0, N=memInfos.size(); i<N; i++) {
16692            ProcessMemInfo mi = memInfos.get(i);
16693
16694            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16695                cachedPss += mi.pss;
16696            }
16697
16698            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16699                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16700                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16701                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16702                if (lastOomAdj != mi.oomAdj) {
16703                    lastOomAdj = mi.oomAdj;
16704                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16705                        tag.append(" / ");
16706                    }
16707                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16708                        if (firstLine) {
16709                            stack.append(":");
16710                            firstLine = false;
16711                        }
16712                        stack.append("\n\t at ");
16713                    } else {
16714                        stack.append("$");
16715                    }
16716                } else {
16717                    tag.append(" ");
16718                    stack.append("$");
16719                }
16720                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16721                    appendMemBucket(tag, mi.pss, mi.name, false);
16722                }
16723                appendMemBucket(stack, mi.pss, mi.name, true);
16724                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16725                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16726                    stack.append("(");
16727                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16728                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16729                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16730                            stack.append(":");
16731                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16732                        }
16733                    }
16734                    stack.append(")");
16735                }
16736            }
16737
16738            appendMemInfo(fullNativeBuilder, mi);
16739            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16740                // The short form only has native processes that are >= 512K.
16741                if (mi.pss >= 512) {
16742                    appendMemInfo(shortNativeBuilder, mi);
16743                } else {
16744                    extraNativeRam += mi.pss;
16745                    extraNativeMemtrack += mi.memtrack;
16746                }
16747            } else {
16748                // Short form has all other details, but if we have collected RAM
16749                // from smaller native processes let's dump a summary of that.
16750                if (extraNativeRam > 0) {
16751                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16752                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16753                    shortNativeBuilder.append('\n');
16754                    extraNativeRam = 0;
16755                }
16756                appendMemInfo(fullJavaBuilder, mi);
16757            }
16758        }
16759
16760        fullJavaBuilder.append("           ");
16761        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16762        fullJavaBuilder.append(": TOTAL");
16763        if (totalMemtrack > 0) {
16764            fullJavaBuilder.append(" (");
16765            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16766            fullJavaBuilder.append(" memtrack)");
16767        } else {
16768        }
16769        fullJavaBuilder.append("\n");
16770
16771        MemInfoReader memInfo = new MemInfoReader();
16772        memInfo.readMemInfo();
16773        final long[] infos = memInfo.getRawInfo();
16774
16775        StringBuilder memInfoBuilder = new StringBuilder(1024);
16776        Debug.getMemInfo(infos);
16777        memInfoBuilder.append("  MemInfo: ");
16778        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16779        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16780        memInfoBuilder.append(stringifyKBSize(
16781                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16782        memInfoBuilder.append(stringifyKBSize(
16783                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16784        memInfoBuilder.append(stringifyKBSize(
16785                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16786        memInfoBuilder.append("           ");
16787        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16788        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16789        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16790        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16791        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16792            memInfoBuilder.append("  ZRAM: ");
16793            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16794            memInfoBuilder.append(" RAM, ");
16795            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16796            memInfoBuilder.append(" swap total, ");
16797            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16798            memInfoBuilder.append(" swap free\n");
16799        }
16800        final long[] ksm = getKsmInfo();
16801        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16802                || ksm[KSM_VOLATILE] != 0) {
16803            memInfoBuilder.append("  KSM: ");
16804            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16805            memInfoBuilder.append(" saved from shared ");
16806            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16807            memInfoBuilder.append("\n       ");
16808            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16809            memInfoBuilder.append(" unshared; ");
16810            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16811            memInfoBuilder.append(" volatile\n");
16812        }
16813        memInfoBuilder.append("  Free RAM: ");
16814        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16815                + memInfo.getFreeSizeKb()));
16816        memInfoBuilder.append("\n");
16817        memInfoBuilder.append("  Used RAM: ");
16818        memInfoBuilder.append(stringifyKBSize(
16819                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16820        memInfoBuilder.append("\n");
16821        memInfoBuilder.append("  Lost RAM: ");
16822        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16823                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16824                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16825        memInfoBuilder.append("\n");
16826        Slog.i(TAG, "Low on memory:");
16827        Slog.i(TAG, shortNativeBuilder.toString());
16828        Slog.i(TAG, fullJavaBuilder.toString());
16829        Slog.i(TAG, memInfoBuilder.toString());
16830
16831        StringBuilder dropBuilder = new StringBuilder(1024);
16832        /*
16833        StringWriter oomSw = new StringWriter();
16834        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16835        StringWriter catSw = new StringWriter();
16836        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16837        String[] emptyArgs = new String[] { };
16838        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16839        oomPw.flush();
16840        String oomString = oomSw.toString();
16841        */
16842        dropBuilder.append("Low on memory:");
16843        dropBuilder.append(stack);
16844        dropBuilder.append('\n');
16845        dropBuilder.append(fullNativeBuilder);
16846        dropBuilder.append(fullJavaBuilder);
16847        dropBuilder.append('\n');
16848        dropBuilder.append(memInfoBuilder);
16849        dropBuilder.append('\n');
16850        /*
16851        dropBuilder.append(oomString);
16852        dropBuilder.append('\n');
16853        */
16854        StringWriter catSw = new StringWriter();
16855        synchronized (ActivityManagerService.this) {
16856            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16857            String[] emptyArgs = new String[] { };
16858            catPw.println();
16859            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16860            catPw.println();
16861            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16862                    false, null).dumpLocked();
16863            catPw.println();
16864            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16865            catPw.flush();
16866        }
16867        dropBuilder.append(catSw.toString());
16868        addErrorToDropBox("lowmem", null, "system_server", null,
16869                null, tag.toString(), dropBuilder.toString(), null, null);
16870        //Slog.i(TAG, "Sent to dropbox:");
16871        //Slog.i(TAG, dropBuilder.toString());
16872        synchronized (ActivityManagerService.this) {
16873            long now = SystemClock.uptimeMillis();
16874            if (mLastMemUsageReportTime < now) {
16875                mLastMemUsageReportTime = now;
16876            }
16877        }
16878    }
16879
16880    /**
16881     * Searches array of arguments for the specified string
16882     * @param args array of argument strings
16883     * @param value value to search for
16884     * @return true if the value is contained in the array
16885     */
16886    private static boolean scanArgs(String[] args, String value) {
16887        if (args != null) {
16888            for (String arg : args) {
16889                if (value.equals(arg)) {
16890                    return true;
16891                }
16892            }
16893        }
16894        return false;
16895    }
16896
16897    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16898            ContentProviderRecord cpr, boolean always) {
16899        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16900
16901        if (!inLaunching || always) {
16902            synchronized (cpr) {
16903                cpr.launchingApp = null;
16904                cpr.notifyAll();
16905            }
16906            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16907            String names[] = cpr.info.authority.split(";");
16908            for (int j = 0; j < names.length; j++) {
16909                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16910            }
16911        }
16912
16913        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16914            ContentProviderConnection conn = cpr.connections.get(i);
16915            if (conn.waiting) {
16916                // If this connection is waiting for the provider, then we don't
16917                // need to mess with its process unless we are always removing
16918                // or for some reason the provider is not currently launching.
16919                if (inLaunching && !always) {
16920                    continue;
16921                }
16922            }
16923            ProcessRecord capp = conn.client;
16924            conn.dead = true;
16925            if (conn.stableCount > 0) {
16926                if (!capp.persistent && capp.thread != null
16927                        && capp.pid != 0
16928                        && capp.pid != MY_PID) {
16929                    capp.kill("depends on provider "
16930                            + cpr.name.flattenToShortString()
16931                            + " in dying proc " + (proc != null ? proc.processName : "??")
16932                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16933                }
16934            } else if (capp.thread != null && conn.provider.provider != null) {
16935                try {
16936                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16937                } catch (RemoteException e) {
16938                }
16939                // In the protocol here, we don't expect the client to correctly
16940                // clean up this connection, we'll just remove it.
16941                cpr.connections.remove(i);
16942                if (conn.client.conProviders.remove(conn)) {
16943                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16944                }
16945            }
16946        }
16947
16948        if (inLaunching && always) {
16949            mLaunchingProviders.remove(cpr);
16950        }
16951        return inLaunching;
16952    }
16953
16954    /**
16955     * Main code for cleaning up a process when it has gone away.  This is
16956     * called both as a result of the process dying, or directly when stopping
16957     * a process when running in single process mode.
16958     *
16959     * @return Returns true if the given process has been restarted, so the
16960     * app that was passed in must remain on the process lists.
16961     */
16962    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16963            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16964        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16965        if (index >= 0) {
16966            removeLruProcessLocked(app);
16967            ProcessList.remove(app.pid);
16968        }
16969
16970        mProcessesToGc.remove(app);
16971        mPendingPssProcesses.remove(app);
16972
16973        // Dismiss any open dialogs.
16974        if (app.crashDialog != null && !app.forceCrashReport) {
16975            app.crashDialog.dismiss();
16976            app.crashDialog = null;
16977        }
16978        if (app.anrDialog != null) {
16979            app.anrDialog.dismiss();
16980            app.anrDialog = null;
16981        }
16982        if (app.waitDialog != null) {
16983            app.waitDialog.dismiss();
16984            app.waitDialog = null;
16985        }
16986
16987        app.crashing = false;
16988        app.notResponding = false;
16989
16990        app.resetPackageList(mProcessStats);
16991        app.unlinkDeathRecipient();
16992        app.makeInactive(mProcessStats);
16993        app.waitingToKill = null;
16994        app.forcingToForeground = null;
16995        updateProcessForegroundLocked(app, false, false);
16996        app.foregroundActivities = false;
16997        app.hasShownUi = false;
16998        app.treatLikeActivity = false;
16999        app.hasAboveClient = false;
17000        app.hasClientActivities = false;
17001
17002        mServices.killServicesLocked(app, allowRestart);
17003
17004        boolean restart = false;
17005
17006        // Remove published content providers.
17007        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17008            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17009            final boolean always = app.bad || !allowRestart;
17010            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17011            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17012                // We left the provider in the launching list, need to
17013                // restart it.
17014                restart = true;
17015            }
17016
17017            cpr.provider = null;
17018            cpr.proc = null;
17019        }
17020        app.pubProviders.clear();
17021
17022        // Take care of any launching providers waiting for this process.
17023        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17024            restart = true;
17025        }
17026
17027        // Unregister from connected content providers.
17028        if (!app.conProviders.isEmpty()) {
17029            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17030                ContentProviderConnection conn = app.conProviders.get(i);
17031                conn.provider.connections.remove(conn);
17032                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17033                        conn.provider.name);
17034            }
17035            app.conProviders.clear();
17036        }
17037
17038        // At this point there may be remaining entries in mLaunchingProviders
17039        // where we were the only one waiting, so they are no longer of use.
17040        // Look for these and clean up if found.
17041        // XXX Commented out for now.  Trying to figure out a way to reproduce
17042        // the actual situation to identify what is actually going on.
17043        if (false) {
17044            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17045                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17046                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17047                    synchronized (cpr) {
17048                        cpr.launchingApp = null;
17049                        cpr.notifyAll();
17050                    }
17051                }
17052            }
17053        }
17054
17055        skipCurrentReceiverLocked(app);
17056
17057        // Unregister any receivers.
17058        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17059            removeReceiverLocked(app.receivers.valueAt(i));
17060        }
17061        app.receivers.clear();
17062
17063        // If the app is undergoing backup, tell the backup manager about it
17064        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17065            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17066                    + mBackupTarget.appInfo + " died during backup");
17067            mHandler.post(new Runnable() {
17068                @Override
17069                public void run(){
17070                    try {
17071                        IBackupManager bm = IBackupManager.Stub.asInterface(
17072                                ServiceManager.getService(Context.BACKUP_SERVICE));
17073                        bm.agentDisconnected(app.info.packageName);
17074                    } catch (RemoteException e) {
17075                        // can't happen; backup manager is local
17076                    }
17077                }
17078            });
17079        }
17080
17081        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17082            ProcessChangeItem item = mPendingProcessChanges.get(i);
17083            if (item.pid == app.pid) {
17084                mPendingProcessChanges.remove(i);
17085                mAvailProcessChanges.add(item);
17086            }
17087        }
17088        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17089                null).sendToTarget();
17090
17091        // If the caller is restarting this app, then leave it in its
17092        // current lists and let the caller take care of it.
17093        if (restarting) {
17094            return false;
17095        }
17096
17097        if (!app.persistent || app.isolated) {
17098            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17099                    "Removing non-persistent process during cleanup: " + app);
17100            if (!replacingPid) {
17101                removeProcessNameLocked(app.processName, app.uid, app);
17102            }
17103            if (mHeavyWeightProcess == app) {
17104                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17105                        mHeavyWeightProcess.userId, 0));
17106                mHeavyWeightProcess = null;
17107            }
17108        } else if (!app.removed) {
17109            // This app is persistent, so we need to keep its record around.
17110            // If it is not already on the pending app list, add it there
17111            // and start a new process for it.
17112            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17113                mPersistentStartingProcesses.add(app);
17114                restart = true;
17115            }
17116        }
17117        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17118                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17119        mProcessesOnHold.remove(app);
17120
17121        if (app == mHomeProcess) {
17122            mHomeProcess = null;
17123        }
17124        if (app == mPreviousProcess) {
17125            mPreviousProcess = null;
17126        }
17127
17128        if (restart && !app.isolated) {
17129            // We have components that still need to be running in the
17130            // process, so re-launch it.
17131            if (index < 0) {
17132                ProcessList.remove(app.pid);
17133            }
17134            addProcessNameLocked(app);
17135            startProcessLocked(app, "restart", app.processName);
17136            return true;
17137        } else if (app.pid > 0 && app.pid != MY_PID) {
17138            // Goodbye!
17139            boolean removed;
17140            synchronized (mPidsSelfLocked) {
17141                mPidsSelfLocked.remove(app.pid);
17142                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17143            }
17144            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17145            if (app.isolated) {
17146                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17147            }
17148            app.setPid(0);
17149        }
17150        return false;
17151    }
17152
17153    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17154        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17155            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17156            if (cpr.launchingApp == app) {
17157                return true;
17158            }
17159        }
17160        return false;
17161    }
17162
17163    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17164        // Look through the content providers we are waiting to have launched,
17165        // and if any run in this process then either schedule a restart of
17166        // the process or kill the client waiting for it if this process has
17167        // gone bad.
17168        boolean restart = false;
17169        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17170            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17171            if (cpr.launchingApp == app) {
17172                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17173                    restart = true;
17174                } else {
17175                    removeDyingProviderLocked(app, cpr, true);
17176                }
17177            }
17178        }
17179        return restart;
17180    }
17181
17182    // =========================================================
17183    // SERVICES
17184    // =========================================================
17185
17186    @Override
17187    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17188            int flags) {
17189        enforceNotIsolatedCaller("getServices");
17190        synchronized (this) {
17191            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17192        }
17193    }
17194
17195    @Override
17196    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17197        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17198        synchronized (this) {
17199            return mServices.getRunningServiceControlPanelLocked(name);
17200        }
17201    }
17202
17203    @Override
17204    public ComponentName startService(IApplicationThread caller, Intent service,
17205            String resolvedType, String callingPackage, int userId)
17206            throws TransactionTooLargeException {
17207        enforceNotIsolatedCaller("startService");
17208        // Refuse possible leaked file descriptors
17209        if (service != null && service.hasFileDescriptors() == true) {
17210            throw new IllegalArgumentException("File descriptors passed in Intent");
17211        }
17212
17213        if (callingPackage == null) {
17214            throw new IllegalArgumentException("callingPackage cannot be null");
17215        }
17216
17217        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17218                "startService: " + service + " type=" + resolvedType);
17219        synchronized(this) {
17220            final int callingPid = Binder.getCallingPid();
17221            final int callingUid = Binder.getCallingUid();
17222            final long origId = Binder.clearCallingIdentity();
17223            ComponentName res = mServices.startServiceLocked(caller, service,
17224                    resolvedType, callingPid, callingUid, callingPackage, userId);
17225            Binder.restoreCallingIdentity(origId);
17226            return res;
17227        }
17228    }
17229
17230    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17231            String callingPackage, int userId)
17232            throws TransactionTooLargeException {
17233        synchronized(this) {
17234            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17235                    "startServiceInPackage: " + service + " type=" + resolvedType);
17236            final long origId = Binder.clearCallingIdentity();
17237            ComponentName res = mServices.startServiceLocked(null, service,
17238                    resolvedType, -1, uid, callingPackage, userId);
17239            Binder.restoreCallingIdentity(origId);
17240            return res;
17241        }
17242    }
17243
17244    @Override
17245    public int stopService(IApplicationThread caller, Intent service,
17246            String resolvedType, int userId) {
17247        enforceNotIsolatedCaller("stopService");
17248        // Refuse possible leaked file descriptors
17249        if (service != null && service.hasFileDescriptors() == true) {
17250            throw new IllegalArgumentException("File descriptors passed in Intent");
17251        }
17252
17253        synchronized(this) {
17254            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17255        }
17256    }
17257
17258    @Override
17259    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17260        enforceNotIsolatedCaller("peekService");
17261        // Refuse possible leaked file descriptors
17262        if (service != null && service.hasFileDescriptors() == true) {
17263            throw new IllegalArgumentException("File descriptors passed in Intent");
17264        }
17265
17266        if (callingPackage == null) {
17267            throw new IllegalArgumentException("callingPackage cannot be null");
17268        }
17269
17270        synchronized(this) {
17271            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17272        }
17273    }
17274
17275    @Override
17276    public boolean stopServiceToken(ComponentName className, IBinder token,
17277            int startId) {
17278        synchronized(this) {
17279            return mServices.stopServiceTokenLocked(className, token, startId);
17280        }
17281    }
17282
17283    @Override
17284    public void setServiceForeground(ComponentName className, IBinder token,
17285            int id, Notification notification, int flags) {
17286        synchronized(this) {
17287            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17288        }
17289    }
17290
17291    @Override
17292    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17293            boolean requireFull, String name, String callerPackage) {
17294        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17295                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17296    }
17297
17298    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17299            String className, int flags) {
17300        boolean result = false;
17301        // For apps that don't have pre-defined UIDs, check for permission
17302        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17303            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17304                if (ActivityManager.checkUidPermission(
17305                        INTERACT_ACROSS_USERS,
17306                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17307                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17308                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17309                            + " requests FLAG_SINGLE_USER, but app does not hold "
17310                            + INTERACT_ACROSS_USERS;
17311                    Slog.w(TAG, msg);
17312                    throw new SecurityException(msg);
17313                }
17314                // Permission passed
17315                result = true;
17316            }
17317        } else if ("system".equals(componentProcessName)) {
17318            result = true;
17319        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17320            // Phone app and persistent apps are allowed to export singleuser providers.
17321            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17322                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17323        }
17324        if (DEBUG_MU) Slog.v(TAG_MU,
17325                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17326                + Integer.toHexString(flags) + ") = " + result);
17327        return result;
17328    }
17329
17330    /**
17331     * Checks to see if the caller is in the same app as the singleton
17332     * component, or the component is in a special app. It allows special apps
17333     * to export singleton components but prevents exporting singleton
17334     * components for regular apps.
17335     */
17336    boolean isValidSingletonCall(int callingUid, int componentUid) {
17337        int componentAppId = UserHandle.getAppId(componentUid);
17338        return UserHandle.isSameApp(callingUid, componentUid)
17339                || componentAppId == Process.SYSTEM_UID
17340                || componentAppId == Process.PHONE_UID
17341                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17342                        == PackageManager.PERMISSION_GRANTED;
17343    }
17344
17345    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17346            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17347            int userId) throws TransactionTooLargeException {
17348        enforceNotIsolatedCaller("bindService");
17349
17350        // Refuse possible leaked file descriptors
17351        if (service != null && service.hasFileDescriptors() == true) {
17352            throw new IllegalArgumentException("File descriptors passed in Intent");
17353        }
17354
17355        if (callingPackage == null) {
17356            throw new IllegalArgumentException("callingPackage cannot be null");
17357        }
17358
17359        synchronized(this) {
17360            return mServices.bindServiceLocked(caller, token, service,
17361                    resolvedType, connection, flags, callingPackage, userId);
17362        }
17363    }
17364
17365    public boolean unbindService(IServiceConnection connection) {
17366        synchronized (this) {
17367            return mServices.unbindServiceLocked(connection);
17368        }
17369    }
17370
17371    public void publishService(IBinder token, Intent intent, IBinder service) {
17372        // Refuse possible leaked file descriptors
17373        if (intent != null && intent.hasFileDescriptors() == true) {
17374            throw new IllegalArgumentException("File descriptors passed in Intent");
17375        }
17376
17377        synchronized(this) {
17378            if (!(token instanceof ServiceRecord)) {
17379                throw new IllegalArgumentException("Invalid service token");
17380            }
17381            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17382        }
17383    }
17384
17385    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17386        // Refuse possible leaked file descriptors
17387        if (intent != null && intent.hasFileDescriptors() == true) {
17388            throw new IllegalArgumentException("File descriptors passed in Intent");
17389        }
17390
17391        synchronized(this) {
17392            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17393        }
17394    }
17395
17396    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17397        synchronized(this) {
17398            if (!(token instanceof ServiceRecord)) {
17399                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17400                throw new IllegalArgumentException("Invalid service token");
17401            }
17402            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17403        }
17404    }
17405
17406    // =========================================================
17407    // BACKUP AND RESTORE
17408    // =========================================================
17409
17410    // Cause the target app to be launched if necessary and its backup agent
17411    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17412    // activity manager to announce its creation.
17413    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17414        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17415        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17416
17417        IPackageManager pm = AppGlobals.getPackageManager();
17418        ApplicationInfo app = null;
17419        try {
17420            app = pm.getApplicationInfo(packageName, 0, userId);
17421        } catch (RemoteException e) {
17422            // can't happen; package manager is process-local
17423        }
17424        if (app == null) {
17425            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17426            return false;
17427        }
17428
17429        synchronized(this) {
17430            // !!! TODO: currently no check here that we're already bound
17431            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17432            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17433            synchronized (stats) {
17434                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17435            }
17436
17437            // Backup agent is now in use, its package can't be stopped.
17438            try {
17439                AppGlobals.getPackageManager().setPackageStoppedState(
17440                        app.packageName, false, UserHandle.getUserId(app.uid));
17441            } catch (RemoteException e) {
17442            } catch (IllegalArgumentException e) {
17443                Slog.w(TAG, "Failed trying to unstop package "
17444                        + app.packageName + ": " + e);
17445            }
17446
17447            BackupRecord r = new BackupRecord(ss, app, backupMode);
17448            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17449                    ? new ComponentName(app.packageName, app.backupAgentName)
17450                    : new ComponentName("android", "FullBackupAgent");
17451            // startProcessLocked() returns existing proc's record if it's already running
17452            ProcessRecord proc = startProcessLocked(app.processName, app,
17453                    false, 0, "backup", hostingName, false, false, false);
17454            if (proc == null) {
17455                Slog.e(TAG, "Unable to start backup agent process " + r);
17456                return false;
17457            }
17458
17459            // If the app is a regular app (uid >= 10000) and not the system server or phone
17460            // process, etc, then mark it as being in full backup so that certain calls to the
17461            // process can be blocked. This is not reset to false anywhere because we kill the
17462            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17463            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17464                proc.inFullBackup = true;
17465            }
17466            r.app = proc;
17467            mBackupTarget = r;
17468            mBackupAppName = app.packageName;
17469
17470            // Try not to kill the process during backup
17471            updateOomAdjLocked(proc);
17472
17473            // If the process is already attached, schedule the creation of the backup agent now.
17474            // If it is not yet live, this will be done when it attaches to the framework.
17475            if (proc.thread != null) {
17476                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17477                try {
17478                    proc.thread.scheduleCreateBackupAgent(app,
17479                            compatibilityInfoForPackageLocked(app), backupMode);
17480                } catch (RemoteException e) {
17481                    // Will time out on the backup manager side
17482                }
17483            } else {
17484                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17485            }
17486            // Invariants: at this point, the target app process exists and the application
17487            // is either already running or in the process of coming up.  mBackupTarget and
17488            // mBackupAppName describe the app, so that when it binds back to the AM we
17489            // know that it's scheduled for a backup-agent operation.
17490        }
17491
17492        return true;
17493    }
17494
17495    @Override
17496    public void clearPendingBackup() {
17497        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17498        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17499
17500        synchronized (this) {
17501            mBackupTarget = null;
17502            mBackupAppName = null;
17503        }
17504    }
17505
17506    // A backup agent has just come up
17507    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17508        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17509                + " = " + agent);
17510
17511        synchronized(this) {
17512            if (!agentPackageName.equals(mBackupAppName)) {
17513                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17514                return;
17515            }
17516        }
17517
17518        long oldIdent = Binder.clearCallingIdentity();
17519        try {
17520            IBackupManager bm = IBackupManager.Stub.asInterface(
17521                    ServiceManager.getService(Context.BACKUP_SERVICE));
17522            bm.agentConnected(agentPackageName, agent);
17523        } catch (RemoteException e) {
17524            // can't happen; the backup manager service is local
17525        } catch (Exception e) {
17526            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17527            e.printStackTrace();
17528        } finally {
17529            Binder.restoreCallingIdentity(oldIdent);
17530        }
17531    }
17532
17533    // done with this agent
17534    public void unbindBackupAgent(ApplicationInfo appInfo) {
17535        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17536        if (appInfo == null) {
17537            Slog.w(TAG, "unbind backup agent for null app");
17538            return;
17539        }
17540
17541        synchronized(this) {
17542            try {
17543                if (mBackupAppName == null) {
17544                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17545                    return;
17546                }
17547
17548                if (!mBackupAppName.equals(appInfo.packageName)) {
17549                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17550                    return;
17551                }
17552
17553                // Not backing this app up any more; reset its OOM adjustment
17554                final ProcessRecord proc = mBackupTarget.app;
17555                updateOomAdjLocked(proc);
17556
17557                // If the app crashed during backup, 'thread' will be null here
17558                if (proc.thread != null) {
17559                    try {
17560                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17561                                compatibilityInfoForPackageLocked(appInfo));
17562                    } catch (Exception e) {
17563                        Slog.e(TAG, "Exception when unbinding backup agent:");
17564                        e.printStackTrace();
17565                    }
17566                }
17567            } finally {
17568                mBackupTarget = null;
17569                mBackupAppName = null;
17570            }
17571        }
17572    }
17573    // =========================================================
17574    // BROADCASTS
17575    // =========================================================
17576
17577    boolean isPendingBroadcastProcessLocked(int pid) {
17578        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17579                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17580    }
17581
17582    void skipPendingBroadcastLocked(int pid) {
17583            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17584            for (BroadcastQueue queue : mBroadcastQueues) {
17585                queue.skipPendingBroadcastLocked(pid);
17586            }
17587    }
17588
17589    // The app just attached; send any pending broadcasts that it should receive
17590    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17591        boolean didSomething = false;
17592        for (BroadcastQueue queue : mBroadcastQueues) {
17593            didSomething |= queue.sendPendingBroadcastsLocked(app);
17594        }
17595        return didSomething;
17596    }
17597
17598    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17599            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17600        enforceNotIsolatedCaller("registerReceiver");
17601        ArrayList<Intent> stickyIntents = null;
17602        ProcessRecord callerApp = null;
17603        int callingUid;
17604        int callingPid;
17605        synchronized(this) {
17606            if (caller != null) {
17607                callerApp = getRecordForAppLocked(caller);
17608                if (callerApp == null) {
17609                    throw new SecurityException(
17610                            "Unable to find app for caller " + caller
17611                            + " (pid=" + Binder.getCallingPid()
17612                            + ") when registering receiver " + receiver);
17613                }
17614                if (callerApp.info.uid != Process.SYSTEM_UID &&
17615                        !callerApp.pkgList.containsKey(callerPackage) &&
17616                        !"android".equals(callerPackage)) {
17617                    throw new SecurityException("Given caller package " + callerPackage
17618                            + " is not running in process " + callerApp);
17619                }
17620                callingUid = callerApp.info.uid;
17621                callingPid = callerApp.pid;
17622            } else {
17623                callerPackage = null;
17624                callingUid = Binder.getCallingUid();
17625                callingPid = Binder.getCallingPid();
17626            }
17627
17628            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17629                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17630
17631            Iterator<String> actions = filter.actionsIterator();
17632            if (actions == null) {
17633                ArrayList<String> noAction = new ArrayList<String>(1);
17634                noAction.add(null);
17635                actions = noAction.iterator();
17636            }
17637
17638            // Collect stickies of users
17639            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17640            while (actions.hasNext()) {
17641                String action = actions.next();
17642                for (int id : userIds) {
17643                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17644                    if (stickies != null) {
17645                        ArrayList<Intent> intents = stickies.get(action);
17646                        if (intents != null) {
17647                            if (stickyIntents == null) {
17648                                stickyIntents = new ArrayList<Intent>();
17649                            }
17650                            stickyIntents.addAll(intents);
17651                        }
17652                    }
17653                }
17654            }
17655        }
17656
17657        ArrayList<Intent> allSticky = null;
17658        if (stickyIntents != null) {
17659            final ContentResolver resolver = mContext.getContentResolver();
17660            // Look for any matching sticky broadcasts...
17661            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17662                Intent intent = stickyIntents.get(i);
17663                // If intent has scheme "content", it will need to acccess
17664                // provider that needs to lock mProviderMap in ActivityThread
17665                // and also it may need to wait application response, so we
17666                // cannot lock ActivityManagerService here.
17667                if (filter.match(resolver, intent, true, TAG) >= 0) {
17668                    if (allSticky == null) {
17669                        allSticky = new ArrayList<Intent>();
17670                    }
17671                    allSticky.add(intent);
17672                }
17673            }
17674        }
17675
17676        // The first sticky in the list is returned directly back to the client.
17677        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17678        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17679        if (receiver == null) {
17680            return sticky;
17681        }
17682
17683        synchronized (this) {
17684            if (callerApp != null && (callerApp.thread == null
17685                    || callerApp.thread.asBinder() != caller.asBinder())) {
17686                // Original caller already died
17687                return null;
17688            }
17689            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17690            if (rl == null) {
17691                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17692                        userId, receiver);
17693                if (rl.app != null) {
17694                    rl.app.receivers.add(rl);
17695                } else {
17696                    try {
17697                        receiver.asBinder().linkToDeath(rl, 0);
17698                    } catch (RemoteException e) {
17699                        return sticky;
17700                    }
17701                    rl.linkedToDeath = true;
17702                }
17703                mRegisteredReceivers.put(receiver.asBinder(), rl);
17704            } else if (rl.uid != callingUid) {
17705                throw new IllegalArgumentException(
17706                        "Receiver requested to register for uid " + callingUid
17707                        + " was previously registered for uid " + rl.uid);
17708            } else if (rl.pid != callingPid) {
17709                throw new IllegalArgumentException(
17710                        "Receiver requested to register for pid " + callingPid
17711                        + " was previously registered for pid " + rl.pid);
17712            } else if (rl.userId != userId) {
17713                throw new IllegalArgumentException(
17714                        "Receiver requested to register for user " + userId
17715                        + " was previously registered for user " + rl.userId);
17716            }
17717            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17718                    permission, callingUid, userId);
17719            rl.add(bf);
17720            if (!bf.debugCheck()) {
17721                Slog.w(TAG, "==> For Dynamic broadcast");
17722            }
17723            mReceiverResolver.addFilter(bf);
17724
17725            // Enqueue broadcasts for all existing stickies that match
17726            // this filter.
17727            if (allSticky != null) {
17728                ArrayList receivers = new ArrayList();
17729                receivers.add(bf);
17730
17731                final int stickyCount = allSticky.size();
17732                for (int i = 0; i < stickyCount; i++) {
17733                    Intent intent = allSticky.get(i);
17734                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17735                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17736                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17737                            null, 0, null, null, false, true, true, -1);
17738                    queue.enqueueParallelBroadcastLocked(r);
17739                    queue.scheduleBroadcastsLocked();
17740                }
17741            }
17742
17743            return sticky;
17744        }
17745    }
17746
17747    public void unregisterReceiver(IIntentReceiver receiver) {
17748        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17749
17750        final long origId = Binder.clearCallingIdentity();
17751        try {
17752            boolean doTrim = false;
17753
17754            synchronized(this) {
17755                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17756                if (rl != null) {
17757                    final BroadcastRecord r = rl.curBroadcast;
17758                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17759                        final boolean doNext = r.queue.finishReceiverLocked(
17760                                r, r.resultCode, r.resultData, r.resultExtras,
17761                                r.resultAbort, false);
17762                        if (doNext) {
17763                            doTrim = true;
17764                            r.queue.processNextBroadcast(false);
17765                        }
17766                    }
17767
17768                    if (rl.app != null) {
17769                        rl.app.receivers.remove(rl);
17770                    }
17771                    removeReceiverLocked(rl);
17772                    if (rl.linkedToDeath) {
17773                        rl.linkedToDeath = false;
17774                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17775                    }
17776                }
17777            }
17778
17779            // If we actually concluded any broadcasts, we might now be able
17780            // to trim the recipients' apps from our working set
17781            if (doTrim) {
17782                trimApplications();
17783                return;
17784            }
17785
17786        } finally {
17787            Binder.restoreCallingIdentity(origId);
17788        }
17789    }
17790
17791    void removeReceiverLocked(ReceiverList rl) {
17792        mRegisteredReceivers.remove(rl.receiver.asBinder());
17793        for (int i = rl.size() - 1; i >= 0; i--) {
17794            mReceiverResolver.removeFilter(rl.get(i));
17795        }
17796    }
17797
17798    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17799        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17800            ProcessRecord r = mLruProcesses.get(i);
17801            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17802                try {
17803                    r.thread.dispatchPackageBroadcast(cmd, packages);
17804                } catch (RemoteException ex) {
17805                }
17806            }
17807        }
17808    }
17809
17810    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17811            int callingUid, int[] users) {
17812        // TODO: come back and remove this assumption to triage all broadcasts
17813        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17814
17815        List<ResolveInfo> receivers = null;
17816        try {
17817            HashSet<ComponentName> singleUserReceivers = null;
17818            boolean scannedFirstReceivers = false;
17819            for (int user : users) {
17820                // Skip users that have Shell restrictions, with exception of always permitted
17821                // Shell broadcasts
17822                if (callingUid == Process.SHELL_UID
17823                        && mUserController.hasUserRestriction(
17824                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17825                        && !isPermittedShellBroadcast(intent)) {
17826                    continue;
17827                }
17828                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17829                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17830                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17831                    // If this is not the system user, we need to check for
17832                    // any receivers that should be filtered out.
17833                    for (int i=0; i<newReceivers.size(); i++) {
17834                        ResolveInfo ri = newReceivers.get(i);
17835                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17836                            newReceivers.remove(i);
17837                            i--;
17838                        }
17839                    }
17840                }
17841                if (newReceivers != null && newReceivers.size() == 0) {
17842                    newReceivers = null;
17843                }
17844                if (receivers == null) {
17845                    receivers = newReceivers;
17846                } else if (newReceivers != null) {
17847                    // We need to concatenate the additional receivers
17848                    // found with what we have do far.  This would be easy,
17849                    // but we also need to de-dup any receivers that are
17850                    // singleUser.
17851                    if (!scannedFirstReceivers) {
17852                        // Collect any single user receivers we had already retrieved.
17853                        scannedFirstReceivers = true;
17854                        for (int i=0; i<receivers.size(); i++) {
17855                            ResolveInfo ri = receivers.get(i);
17856                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17857                                ComponentName cn = new ComponentName(
17858                                        ri.activityInfo.packageName, ri.activityInfo.name);
17859                                if (singleUserReceivers == null) {
17860                                    singleUserReceivers = new HashSet<ComponentName>();
17861                                }
17862                                singleUserReceivers.add(cn);
17863                            }
17864                        }
17865                    }
17866                    // Add the new results to the existing results, tracking
17867                    // and de-dupping single user receivers.
17868                    for (int i=0; i<newReceivers.size(); i++) {
17869                        ResolveInfo ri = newReceivers.get(i);
17870                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17871                            ComponentName cn = new ComponentName(
17872                                    ri.activityInfo.packageName, ri.activityInfo.name);
17873                            if (singleUserReceivers == null) {
17874                                singleUserReceivers = new HashSet<ComponentName>();
17875                            }
17876                            if (!singleUserReceivers.contains(cn)) {
17877                                singleUserReceivers.add(cn);
17878                                receivers.add(ri);
17879                            }
17880                        } else {
17881                            receivers.add(ri);
17882                        }
17883                    }
17884                }
17885            }
17886        } catch (RemoteException ex) {
17887            // pm is in same process, this will never happen.
17888        }
17889        return receivers;
17890    }
17891
17892    private boolean isPermittedShellBroadcast(Intent intent) {
17893        // remote bugreport should always be allowed to be taken
17894        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17895    }
17896
17897    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17898            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17899        final String action = intent.getAction();
17900        if (isProtectedBroadcast
17901                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17902                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17903                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17904                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17905                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17906                || Intent.ACTION_MASTER_CLEAR.equals(action)
17907                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17908                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17909                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17910                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17911                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17912            // Broadcast is either protected, or it's a public action that
17913            // we've relaxed, so it's fine for system internals to send.
17914            return;
17915        }
17916
17917        // This broadcast may be a problem...  but there are often system components that
17918        // want to send an internal broadcast to themselves, which is annoying to have to
17919        // explicitly list each action as a protected broadcast, so we will check for that
17920        // one safe case and allow it: an explicit broadcast, only being received by something
17921        // that has protected itself.
17922        if (receivers != null && receivers.size() > 0
17923                && (intent.getPackage() != null || intent.getComponent() != null)) {
17924            boolean allProtected = true;
17925            for (int i = receivers.size()-1; i >= 0; i--) {
17926                Object target = receivers.get(i);
17927                if (target instanceof ResolveInfo) {
17928                    ResolveInfo ri = (ResolveInfo)target;
17929                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17930                        allProtected = false;
17931                        break;
17932                    }
17933                } else {
17934                    BroadcastFilter bf = (BroadcastFilter)target;
17935                    if (bf.requiredPermission == null) {
17936                        allProtected = false;
17937                        break;
17938                    }
17939                }
17940            }
17941            if (allProtected) {
17942                // All safe!
17943                return;
17944            }
17945        }
17946
17947        // The vast majority of broadcasts sent from system internals
17948        // should be protected to avoid security holes, so yell loudly
17949        // to ensure we examine these cases.
17950        if (callerApp != null) {
17951            Log.wtf(TAG, "Sending non-protected broadcast " + action
17952                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17953                    new Throwable());
17954        } else {
17955            Log.wtf(TAG, "Sending non-protected broadcast " + action
17956                            + " from system uid " + UserHandle.formatUid(callingUid)
17957                            + " pkg " + callerPackage,
17958                    new Throwable());
17959        }
17960    }
17961
17962    final int broadcastIntentLocked(ProcessRecord callerApp,
17963            String callerPackage, Intent intent, String resolvedType,
17964            IIntentReceiver resultTo, int resultCode, String resultData,
17965            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17966            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17967        intent = new Intent(intent);
17968
17969        // By default broadcasts do not go to stopped apps.
17970        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17971
17972        // If we have not finished booting, don't allow this to launch new processes.
17973        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17974            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17975        }
17976
17977        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17978                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17979                + " ordered=" + ordered + " userid=" + userId);
17980        if ((resultTo != null) && !ordered) {
17981            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17982        }
17983
17984        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17985                ALLOW_NON_FULL, "broadcast", callerPackage);
17986
17987        // Make sure that the user who is receiving this broadcast is running.
17988        // If not, we will just skip it. Make an exception for shutdown broadcasts
17989        // and upgrade steps.
17990
17991        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17992            if ((callingUid != Process.SYSTEM_UID
17993                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17994                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17995                Slog.w(TAG, "Skipping broadcast of " + intent
17996                        + ": user " + userId + " is stopped");
17997                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17998            }
17999        }
18000
18001        BroadcastOptions brOptions = null;
18002        if (bOptions != null) {
18003            brOptions = new BroadcastOptions(bOptions);
18004            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18005                // See if the caller is allowed to do this.  Note we are checking against
18006                // the actual real caller (not whoever provided the operation as say a
18007                // PendingIntent), because that who is actually supplied the arguments.
18008                if (checkComponentPermission(
18009                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18010                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18011                        != PackageManager.PERMISSION_GRANTED) {
18012                    String msg = "Permission Denial: " + intent.getAction()
18013                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18014                            + ", uid=" + callingUid + ")"
18015                            + " requires "
18016                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18017                    Slog.w(TAG, msg);
18018                    throw new SecurityException(msg);
18019                }
18020            }
18021        }
18022
18023        // Verify that protected broadcasts are only being sent by system code,
18024        // and that system code is only sending protected broadcasts.
18025        final String action = intent.getAction();
18026        final boolean isProtectedBroadcast;
18027        try {
18028            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18029        } catch (RemoteException e) {
18030            Slog.w(TAG, "Remote exception", e);
18031            return ActivityManager.BROADCAST_SUCCESS;
18032        }
18033
18034        final boolean isCallerSystem;
18035        switch (UserHandle.getAppId(callingUid)) {
18036            case Process.ROOT_UID:
18037            case Process.SYSTEM_UID:
18038            case Process.PHONE_UID:
18039            case Process.BLUETOOTH_UID:
18040            case Process.NFC_UID:
18041                isCallerSystem = true;
18042                break;
18043            default:
18044                isCallerSystem = (callerApp != null) && callerApp.persistent;
18045                break;
18046        }
18047
18048        // First line security check before anything else: stop non-system apps from
18049        // sending protected broadcasts.
18050        if (!isCallerSystem) {
18051            if (isProtectedBroadcast) {
18052                String msg = "Permission Denial: not allowed to send broadcast "
18053                        + action + " from pid="
18054                        + callingPid + ", uid=" + callingUid;
18055                Slog.w(TAG, msg);
18056                throw new SecurityException(msg);
18057
18058            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18059                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18060                // Special case for compatibility: we don't want apps to send this,
18061                // but historically it has not been protected and apps may be using it
18062                // to poke their own app widget.  So, instead of making it protected,
18063                // just limit it to the caller.
18064                if (callerPackage == null) {
18065                    String msg = "Permission Denial: not allowed to send broadcast "
18066                            + action + " from unknown caller.";
18067                    Slog.w(TAG, msg);
18068                    throw new SecurityException(msg);
18069                } else if (intent.getComponent() != null) {
18070                    // They are good enough to send to an explicit component...  verify
18071                    // it is being sent to the calling app.
18072                    if (!intent.getComponent().getPackageName().equals(
18073                            callerPackage)) {
18074                        String msg = "Permission Denial: not allowed to send broadcast "
18075                                + action + " to "
18076                                + intent.getComponent().getPackageName() + " from "
18077                                + callerPackage;
18078                        Slog.w(TAG, msg);
18079                        throw new SecurityException(msg);
18080                    }
18081                } else {
18082                    // Limit broadcast to their own package.
18083                    intent.setPackage(callerPackage);
18084                }
18085            }
18086        }
18087
18088        if (action != null) {
18089            switch (action) {
18090                case Intent.ACTION_UID_REMOVED:
18091                case Intent.ACTION_PACKAGE_REMOVED:
18092                case Intent.ACTION_PACKAGE_CHANGED:
18093                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18094                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18095                case Intent.ACTION_PACKAGES_SUSPENDED:
18096                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18097                    // Handle special intents: if this broadcast is from the package
18098                    // manager about a package being removed, we need to remove all of
18099                    // its activities from the history stack.
18100                    if (checkComponentPermission(
18101                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18102                            callingPid, callingUid, -1, true)
18103                            != PackageManager.PERMISSION_GRANTED) {
18104                        String msg = "Permission Denial: " + intent.getAction()
18105                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18106                                + ", uid=" + callingUid + ")"
18107                                + " requires "
18108                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18109                        Slog.w(TAG, msg);
18110                        throw new SecurityException(msg);
18111                    }
18112                    switch (action) {
18113                        case Intent.ACTION_UID_REMOVED:
18114                            final Bundle intentExtras = intent.getExtras();
18115                            final int uid = intentExtras != null
18116                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18117                            if (uid >= 0) {
18118                                mBatteryStatsService.removeUid(uid);
18119                                mAppOpsService.uidRemoved(uid);
18120                            }
18121                            break;
18122                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18123                            // If resources are unavailable just force stop all those packages
18124                            // and flush the attribute cache as well.
18125                            String list[] =
18126                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18127                            if (list != null && list.length > 0) {
18128                                for (int i = 0; i < list.length; i++) {
18129                                    forceStopPackageLocked(list[i], -1, false, true, true,
18130                                            false, false, userId, "storage unmount");
18131                                }
18132                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18133                                sendPackageBroadcastLocked(
18134                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18135                                        userId);
18136                            }
18137                            break;
18138                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18139                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18140                            break;
18141                        case Intent.ACTION_PACKAGE_REMOVED:
18142                        case Intent.ACTION_PACKAGE_CHANGED:
18143                            Uri data = intent.getData();
18144                            String ssp;
18145                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18146                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18147                                final boolean replacing =
18148                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18149                                final boolean killProcess =
18150                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18151                                final boolean fullUninstall = removed && !replacing;
18152                                if (removed) {
18153                                    if (killProcess) {
18154                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18155                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18156                                                false, true, true, false, fullUninstall, userId,
18157                                                removed ? "pkg removed" : "pkg changed");
18158                                    }
18159                                    final int cmd = killProcess
18160                                            ? IApplicationThread.PACKAGE_REMOVED
18161                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18162                                    sendPackageBroadcastLocked(cmd,
18163                                            new String[] {ssp}, userId);
18164                                    if (fullUninstall) {
18165                                        mAppOpsService.packageRemoved(
18166                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18167
18168                                        // Remove all permissions granted from/to this package
18169                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18170
18171                                        removeTasksByPackageNameLocked(ssp, userId);
18172
18173                                        // Hide the "unsupported display" dialog if necessary.
18174                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18175                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18176                                            mUnsupportedDisplaySizeDialog.dismiss();
18177                                            mUnsupportedDisplaySizeDialog = null;
18178                                        }
18179                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18180                                        mBatteryStatsService.notePackageUninstalled(ssp);
18181                                    }
18182                                } else {
18183                                    if (killProcess) {
18184                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18185                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18186                                                userId, ProcessList.INVALID_ADJ,
18187                                                false, true, true, false, "change " + ssp);
18188                                    }
18189                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18190                                            intent.getStringArrayExtra(
18191                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18192                                }
18193                            }
18194                            break;
18195                        case Intent.ACTION_PACKAGES_SUSPENDED:
18196                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18197                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18198                                    intent.getAction());
18199                            final String[] packageNames = intent.getStringArrayExtra(
18200                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18201                            final int userHandle = intent.getIntExtra(
18202                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18203
18204                            synchronized(ActivityManagerService.this) {
18205                                mRecentTasks.onPackagesSuspendedChanged(
18206                                        packageNames, suspended, userHandle);
18207                            }
18208                            break;
18209                    }
18210                    break;
18211                case Intent.ACTION_PACKAGE_REPLACED:
18212                {
18213                    final Uri data = intent.getData();
18214                    final String ssp;
18215                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18216                        final ApplicationInfo aInfo =
18217                                getPackageManagerInternalLocked().getApplicationInfo(
18218                                        ssp,
18219                                        userId);
18220                        if (aInfo == null) {
18221                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18222                                    + " ssp=" + ssp + " data=" + data);
18223                            return ActivityManager.BROADCAST_SUCCESS;
18224                        }
18225                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18226                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18227                                new String[] {ssp}, userId);
18228                    }
18229                    break;
18230                }
18231                case Intent.ACTION_PACKAGE_ADDED:
18232                {
18233                    // Special case for adding a package: by default turn on compatibility mode.
18234                    Uri data = intent.getData();
18235                    String ssp;
18236                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18237                        final boolean replacing =
18238                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18239                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18240
18241                        try {
18242                            ApplicationInfo ai = AppGlobals.getPackageManager().
18243                                    getApplicationInfo(ssp, 0, 0);
18244                            mBatteryStatsService.notePackageInstalled(ssp,
18245                                    ai != null ? ai.versionCode : 0);
18246                        } catch (RemoteException e) {
18247                        }
18248                    }
18249                    break;
18250                }
18251                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18252                {
18253                    Uri data = intent.getData();
18254                    String ssp;
18255                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18256                        // Hide the "unsupported display" dialog if necessary.
18257                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18258                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18259                            mUnsupportedDisplaySizeDialog.dismiss();
18260                            mUnsupportedDisplaySizeDialog = null;
18261                        }
18262                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18263                    }
18264                    break;
18265                }
18266                case Intent.ACTION_TIMEZONE_CHANGED:
18267                    // If this is the time zone changed action, queue up a message that will reset
18268                    // the timezone of all currently running processes. This message will get
18269                    // queued up before the broadcast happens.
18270                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18271                    break;
18272                case Intent.ACTION_TIME_CHANGED:
18273                    // If the user set the time, let all running processes know.
18274                    final int is24Hour =
18275                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18276                                    : 0;
18277                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18278                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18279                    synchronized (stats) {
18280                        stats.noteCurrentTimeChangedLocked();
18281                    }
18282                    break;
18283                case Intent.ACTION_CLEAR_DNS_CACHE:
18284                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18285                    break;
18286                case Proxy.PROXY_CHANGE_ACTION:
18287                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18288                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18289                    break;
18290                case android.hardware.Camera.ACTION_NEW_PICTURE:
18291                case android.hardware.Camera.ACTION_NEW_VIDEO:
18292                    // These broadcasts are no longer allowed by the system, since they can
18293                    // cause significant thrashing at a crictical point (using the camera).
18294                    // Apps should use JobScehduler to monitor for media provider changes.
18295                    Slog.w(TAG, action + " no longer allowed; dropping from "
18296                            + UserHandle.formatUid(callingUid));
18297                    if (resultTo != null) {
18298                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18299                        try {
18300                            queue.performReceiveLocked(callerApp, resultTo, intent,
18301                                    Activity.RESULT_CANCELED, null, null,
18302                                    false, false, userId);
18303                        } catch (RemoteException e) {
18304                            Slog.w(TAG, "Failure ["
18305                                    + queue.mQueueName + "] sending broadcast result of "
18306                                    + intent, e);
18307
18308                        }
18309                    }
18310                    // Lie; we don't want to crash the app.
18311                    return ActivityManager.BROADCAST_SUCCESS;
18312            }
18313        }
18314
18315        // Add to the sticky list if requested.
18316        if (sticky) {
18317            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18318                    callingPid, callingUid)
18319                    != PackageManager.PERMISSION_GRANTED) {
18320                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18321                        + callingPid + ", uid=" + callingUid
18322                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18323                Slog.w(TAG, msg);
18324                throw new SecurityException(msg);
18325            }
18326            if (requiredPermissions != null && requiredPermissions.length > 0) {
18327                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18328                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18329                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18330            }
18331            if (intent.getComponent() != null) {
18332                throw new SecurityException(
18333                        "Sticky broadcasts can't target a specific component");
18334            }
18335            // We use userId directly here, since the "all" target is maintained
18336            // as a separate set of sticky broadcasts.
18337            if (userId != UserHandle.USER_ALL) {
18338                // But first, if this is not a broadcast to all users, then
18339                // make sure it doesn't conflict with an existing broadcast to
18340                // all users.
18341                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18342                        UserHandle.USER_ALL);
18343                if (stickies != null) {
18344                    ArrayList<Intent> list = stickies.get(intent.getAction());
18345                    if (list != null) {
18346                        int N = list.size();
18347                        int i;
18348                        for (i=0; i<N; i++) {
18349                            if (intent.filterEquals(list.get(i))) {
18350                                throw new IllegalArgumentException(
18351                                        "Sticky broadcast " + intent + " for user "
18352                                        + userId + " conflicts with existing global broadcast");
18353                            }
18354                        }
18355                    }
18356                }
18357            }
18358            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18359            if (stickies == null) {
18360                stickies = new ArrayMap<>();
18361                mStickyBroadcasts.put(userId, stickies);
18362            }
18363            ArrayList<Intent> list = stickies.get(intent.getAction());
18364            if (list == null) {
18365                list = new ArrayList<>();
18366                stickies.put(intent.getAction(), list);
18367            }
18368            final int stickiesCount = list.size();
18369            int i;
18370            for (i = 0; i < stickiesCount; i++) {
18371                if (intent.filterEquals(list.get(i))) {
18372                    // This sticky already exists, replace it.
18373                    list.set(i, new Intent(intent));
18374                    break;
18375                }
18376            }
18377            if (i >= stickiesCount) {
18378                list.add(new Intent(intent));
18379            }
18380        }
18381
18382        int[] users;
18383        if (userId == UserHandle.USER_ALL) {
18384            // Caller wants broadcast to go to all started users.
18385            users = mUserController.getStartedUserArrayLocked();
18386        } else {
18387            // Caller wants broadcast to go to one specific user.
18388            users = new int[] {userId};
18389        }
18390
18391        // Figure out who all will receive this broadcast.
18392        List receivers = null;
18393        List<BroadcastFilter> registeredReceivers = null;
18394        // Need to resolve the intent to interested receivers...
18395        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18396                 == 0) {
18397            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18398        }
18399        if (intent.getComponent() == null) {
18400            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18401                // Query one target user at a time, excluding shell-restricted users
18402                for (int i = 0; i < users.length; i++) {
18403                    if (mUserController.hasUserRestriction(
18404                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18405                        continue;
18406                    }
18407                    List<BroadcastFilter> registeredReceiversForUser =
18408                            mReceiverResolver.queryIntent(intent,
18409                                    resolvedType, false, users[i]);
18410                    if (registeredReceivers == null) {
18411                        registeredReceivers = registeredReceiversForUser;
18412                    } else if (registeredReceiversForUser != null) {
18413                        registeredReceivers.addAll(registeredReceiversForUser);
18414                    }
18415                }
18416            } else {
18417                registeredReceivers = mReceiverResolver.queryIntent(intent,
18418                        resolvedType, false, userId);
18419            }
18420        }
18421
18422        final boolean replacePending =
18423                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18424
18425        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18426                + " replacePending=" + replacePending);
18427
18428        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18429        if (!ordered && NR > 0) {
18430            // If we are not serializing this broadcast, then send the
18431            // registered receivers separately so they don't wait for the
18432            // components to be launched.
18433            if (isCallerSystem) {
18434                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18435                        isProtectedBroadcast, registeredReceivers);
18436            }
18437            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18438            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18439                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18440                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18441                    resultExtras, ordered, sticky, false, userId);
18442            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18443            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18444            if (!replaced) {
18445                queue.enqueueParallelBroadcastLocked(r);
18446                queue.scheduleBroadcastsLocked();
18447            }
18448            registeredReceivers = null;
18449            NR = 0;
18450        }
18451
18452        // Merge into one list.
18453        int ir = 0;
18454        if (receivers != null) {
18455            // A special case for PACKAGE_ADDED: do not allow the package
18456            // being added to see this broadcast.  This prevents them from
18457            // using this as a back door to get run as soon as they are
18458            // installed.  Maybe in the future we want to have a special install
18459            // broadcast or such for apps, but we'd like to deliberately make
18460            // this decision.
18461            String skipPackages[] = null;
18462            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18463                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18464                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18465                Uri data = intent.getData();
18466                if (data != null) {
18467                    String pkgName = data.getSchemeSpecificPart();
18468                    if (pkgName != null) {
18469                        skipPackages = new String[] { pkgName };
18470                    }
18471                }
18472            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18473                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18474            }
18475            if (skipPackages != null && (skipPackages.length > 0)) {
18476                for (String skipPackage : skipPackages) {
18477                    if (skipPackage != null) {
18478                        int NT = receivers.size();
18479                        for (int it=0; it<NT; it++) {
18480                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18481                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18482                                receivers.remove(it);
18483                                it--;
18484                                NT--;
18485                            }
18486                        }
18487                    }
18488                }
18489            }
18490
18491            int NT = receivers != null ? receivers.size() : 0;
18492            int it = 0;
18493            ResolveInfo curt = null;
18494            BroadcastFilter curr = null;
18495            while (it < NT && ir < NR) {
18496                if (curt == null) {
18497                    curt = (ResolveInfo)receivers.get(it);
18498                }
18499                if (curr == null) {
18500                    curr = registeredReceivers.get(ir);
18501                }
18502                if (curr.getPriority() >= curt.priority) {
18503                    // Insert this broadcast record into the final list.
18504                    receivers.add(it, curr);
18505                    ir++;
18506                    curr = null;
18507                    it++;
18508                    NT++;
18509                } else {
18510                    // Skip to the next ResolveInfo in the final list.
18511                    it++;
18512                    curt = null;
18513                }
18514            }
18515        }
18516        while (ir < NR) {
18517            if (receivers == null) {
18518                receivers = new ArrayList();
18519            }
18520            receivers.add(registeredReceivers.get(ir));
18521            ir++;
18522        }
18523
18524        if (isCallerSystem) {
18525            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18526                    isProtectedBroadcast, receivers);
18527        }
18528
18529        if ((receivers != null && receivers.size() > 0)
18530                || resultTo != null) {
18531            BroadcastQueue queue = broadcastQueueForIntent(intent);
18532            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18533                    callerPackage, callingPid, callingUid, resolvedType,
18534                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18535                    resultData, resultExtras, ordered, sticky, false, userId);
18536
18537            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18538                    + ": prev had " + queue.mOrderedBroadcasts.size());
18539            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18540                    "Enqueueing broadcast " + r.intent.getAction());
18541
18542            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18543            if (!replaced) {
18544                queue.enqueueOrderedBroadcastLocked(r);
18545                queue.scheduleBroadcastsLocked();
18546            }
18547        } else {
18548            // There was nobody interested in the broadcast, but we still want to record
18549            // that it happened.
18550            if (intent.getComponent() == null && intent.getPackage() == null
18551                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18552                // This was an implicit broadcast... let's record it for posterity.
18553                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18554            }
18555        }
18556
18557        return ActivityManager.BROADCAST_SUCCESS;
18558    }
18559
18560    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18561            int skipCount, long dispatchTime) {
18562        final long now = SystemClock.elapsedRealtime();
18563        if (mCurBroadcastStats == null ||
18564                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18565            mLastBroadcastStats = mCurBroadcastStats;
18566            if (mLastBroadcastStats != null) {
18567                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18568                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18569            }
18570            mCurBroadcastStats = new BroadcastStats();
18571        }
18572        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18573    }
18574
18575    final Intent verifyBroadcastLocked(Intent intent) {
18576        // Refuse possible leaked file descriptors
18577        if (intent != null && intent.hasFileDescriptors() == true) {
18578            throw new IllegalArgumentException("File descriptors passed in Intent");
18579        }
18580
18581        int flags = intent.getFlags();
18582
18583        if (!mProcessesReady) {
18584            // if the caller really truly claims to know what they're doing, go
18585            // ahead and allow the broadcast without launching any receivers
18586            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18587                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18588            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18589                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18590                        + " before boot completion");
18591                throw new IllegalStateException("Cannot broadcast before boot completed");
18592            }
18593        }
18594
18595        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18596            throw new IllegalArgumentException(
18597                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18598        }
18599
18600        return intent;
18601    }
18602
18603    public final int broadcastIntent(IApplicationThread caller,
18604            Intent intent, String resolvedType, IIntentReceiver resultTo,
18605            int resultCode, String resultData, Bundle resultExtras,
18606            String[] requiredPermissions, int appOp, Bundle bOptions,
18607            boolean serialized, boolean sticky, int userId) {
18608        enforceNotIsolatedCaller("broadcastIntent");
18609        synchronized(this) {
18610            intent = verifyBroadcastLocked(intent);
18611
18612            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18613            final int callingPid = Binder.getCallingPid();
18614            final int callingUid = Binder.getCallingUid();
18615            final long origId = Binder.clearCallingIdentity();
18616            int res = broadcastIntentLocked(callerApp,
18617                    callerApp != null ? callerApp.info.packageName : null,
18618                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18619                    requiredPermissions, appOp, bOptions, serialized, sticky,
18620                    callingPid, callingUid, userId);
18621            Binder.restoreCallingIdentity(origId);
18622            return res;
18623        }
18624    }
18625
18626
18627    int broadcastIntentInPackage(String packageName, int uid,
18628            Intent intent, String resolvedType, IIntentReceiver resultTo,
18629            int resultCode, String resultData, Bundle resultExtras,
18630            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18631            int userId) {
18632        synchronized(this) {
18633            intent = verifyBroadcastLocked(intent);
18634
18635            final long origId = Binder.clearCallingIdentity();
18636            String[] requiredPermissions = requiredPermission == null ? null
18637                    : new String[] {requiredPermission};
18638            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18639                    resultTo, resultCode, resultData, resultExtras,
18640                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18641                    sticky, -1, uid, userId);
18642            Binder.restoreCallingIdentity(origId);
18643            return res;
18644        }
18645    }
18646
18647    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18648        // Refuse possible leaked file descriptors
18649        if (intent != null && intent.hasFileDescriptors() == true) {
18650            throw new IllegalArgumentException("File descriptors passed in Intent");
18651        }
18652
18653        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18654                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18655
18656        synchronized(this) {
18657            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18658                    != PackageManager.PERMISSION_GRANTED) {
18659                String msg = "Permission Denial: unbroadcastIntent() from pid="
18660                        + Binder.getCallingPid()
18661                        + ", uid=" + Binder.getCallingUid()
18662                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18663                Slog.w(TAG, msg);
18664                throw new SecurityException(msg);
18665            }
18666            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18667            if (stickies != null) {
18668                ArrayList<Intent> list = stickies.get(intent.getAction());
18669                if (list != null) {
18670                    int N = list.size();
18671                    int i;
18672                    for (i=0; i<N; i++) {
18673                        if (intent.filterEquals(list.get(i))) {
18674                            list.remove(i);
18675                            break;
18676                        }
18677                    }
18678                    if (list.size() <= 0) {
18679                        stickies.remove(intent.getAction());
18680                    }
18681                }
18682                if (stickies.size() <= 0) {
18683                    mStickyBroadcasts.remove(userId);
18684                }
18685            }
18686        }
18687    }
18688
18689    void backgroundServicesFinishedLocked(int userId) {
18690        for (BroadcastQueue queue : mBroadcastQueues) {
18691            queue.backgroundServicesFinishedLocked(userId);
18692        }
18693    }
18694
18695    public void finishReceiver(IBinder who, int resultCode, String resultData,
18696            Bundle resultExtras, boolean resultAbort, int flags) {
18697        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18698
18699        // Refuse possible leaked file descriptors
18700        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18701            throw new IllegalArgumentException("File descriptors passed in Bundle");
18702        }
18703
18704        final long origId = Binder.clearCallingIdentity();
18705        try {
18706            boolean doNext = false;
18707            BroadcastRecord r;
18708
18709            synchronized(this) {
18710                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18711                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18712                r = queue.getMatchingOrderedReceiver(who);
18713                if (r != null) {
18714                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18715                        resultData, resultExtras, resultAbort, true);
18716                }
18717            }
18718
18719            if (doNext) {
18720                r.queue.processNextBroadcast(false);
18721            }
18722            trimApplications();
18723        } finally {
18724            Binder.restoreCallingIdentity(origId);
18725        }
18726    }
18727
18728    // =========================================================
18729    // INSTRUMENTATION
18730    // =========================================================
18731
18732    public boolean startInstrumentation(ComponentName className,
18733            String profileFile, int flags, Bundle arguments,
18734            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18735            int userId, String abiOverride) {
18736        enforceNotIsolatedCaller("startInstrumentation");
18737        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18738                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18739        // Refuse possible leaked file descriptors
18740        if (arguments != null && arguments.hasFileDescriptors()) {
18741            throw new IllegalArgumentException("File descriptors passed in Bundle");
18742        }
18743
18744        synchronized(this) {
18745            InstrumentationInfo ii = null;
18746            ApplicationInfo ai = null;
18747            try {
18748                ii = mContext.getPackageManager().getInstrumentationInfo(
18749                    className, STOCK_PM_FLAGS);
18750                ai = AppGlobals.getPackageManager().getApplicationInfo(
18751                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18752            } catch (PackageManager.NameNotFoundException e) {
18753            } catch (RemoteException e) {
18754            }
18755            if (ii == null) {
18756                reportStartInstrumentationFailureLocked(watcher, className,
18757                        "Unable to find instrumentation info for: " + className);
18758                return false;
18759            }
18760            if (ai == null) {
18761                reportStartInstrumentationFailureLocked(watcher, className,
18762                        "Unable to find instrumentation target package: " + ii.targetPackage);
18763                return false;
18764            }
18765            if (!ai.hasCode()) {
18766                reportStartInstrumentationFailureLocked(watcher, className,
18767                        "Instrumentation target has no code: " + ii.targetPackage);
18768                return false;
18769            }
18770
18771            int match = mContext.getPackageManager().checkSignatures(
18772                    ii.targetPackage, ii.packageName);
18773            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18774                String msg = "Permission Denial: starting instrumentation "
18775                        + className + " from pid="
18776                        + Binder.getCallingPid()
18777                        + ", uid=" + Binder.getCallingPid()
18778                        + " not allowed because package " + ii.packageName
18779                        + " does not have a signature matching the target "
18780                        + ii.targetPackage;
18781                reportStartInstrumentationFailureLocked(watcher, className, msg);
18782                throw new SecurityException(msg);
18783            }
18784
18785            final long origId = Binder.clearCallingIdentity();
18786            // Instrumentation can kill and relaunch even persistent processes
18787            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18788                    "start instr");
18789            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18790            app.instrumentationClass = className;
18791            app.instrumentationInfo = ai;
18792            app.instrumentationProfileFile = profileFile;
18793            app.instrumentationArguments = arguments;
18794            app.instrumentationWatcher = watcher;
18795            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18796            app.instrumentationResultClass = className;
18797            Binder.restoreCallingIdentity(origId);
18798        }
18799
18800        return true;
18801    }
18802
18803    /**
18804     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18805     * error to the logs, but if somebody is watching, send the report there too.  This enables
18806     * the "am" command to report errors with more information.
18807     *
18808     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18809     * @param cn The component name of the instrumentation.
18810     * @param report The error report.
18811     */
18812    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18813            ComponentName cn, String report) {
18814        Slog.w(TAG, report);
18815        if (watcher != null) {
18816            Bundle results = new Bundle();
18817            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18818            results.putString("Error", report);
18819            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18820        }
18821    }
18822
18823    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18824        if (app.instrumentationWatcher != null) {
18825            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18826                    app.instrumentationClass, resultCode, results);
18827        }
18828
18829        // Can't call out of the system process with a lock held, so post a message.
18830        if (app.instrumentationUiAutomationConnection != null) {
18831            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18832                    app.instrumentationUiAutomationConnection).sendToTarget();
18833        }
18834
18835        app.instrumentationWatcher = null;
18836        app.instrumentationUiAutomationConnection = null;
18837        app.instrumentationClass = null;
18838        app.instrumentationInfo = null;
18839        app.instrumentationProfileFile = null;
18840        app.instrumentationArguments = null;
18841
18842        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18843                "finished inst");
18844    }
18845
18846    public void finishInstrumentation(IApplicationThread target,
18847            int resultCode, Bundle results) {
18848        int userId = UserHandle.getCallingUserId();
18849        // Refuse possible leaked file descriptors
18850        if (results != null && results.hasFileDescriptors()) {
18851            throw new IllegalArgumentException("File descriptors passed in Intent");
18852        }
18853
18854        synchronized(this) {
18855            ProcessRecord app = getRecordForAppLocked(target);
18856            if (app == null) {
18857                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18858                return;
18859            }
18860            final long origId = Binder.clearCallingIdentity();
18861            finishInstrumentationLocked(app, resultCode, results);
18862            Binder.restoreCallingIdentity(origId);
18863        }
18864    }
18865
18866    // =========================================================
18867    // CONFIGURATION
18868    // =========================================================
18869
18870    public ConfigurationInfo getDeviceConfigurationInfo() {
18871        ConfigurationInfo config = new ConfigurationInfo();
18872        synchronized (this) {
18873            config.reqTouchScreen = mConfiguration.touchscreen;
18874            config.reqKeyboardType = mConfiguration.keyboard;
18875            config.reqNavigation = mConfiguration.navigation;
18876            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18877                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18878                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18879            }
18880            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18881                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18882                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18883            }
18884            config.reqGlEsVersion = GL_ES_VERSION;
18885        }
18886        return config;
18887    }
18888
18889    ActivityStack getFocusedStack() {
18890        return mStackSupervisor.getFocusedStack();
18891    }
18892
18893    @Override
18894    public int getFocusedStackId() throws RemoteException {
18895        ActivityStack focusedStack = getFocusedStack();
18896        if (focusedStack != null) {
18897            return focusedStack.getStackId();
18898        }
18899        return -1;
18900    }
18901
18902    public Configuration getConfiguration() {
18903        Configuration ci;
18904        synchronized(this) {
18905            ci = new Configuration(mConfiguration);
18906            ci.userSetLocale = false;
18907        }
18908        return ci;
18909    }
18910
18911    @Override
18912    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18913        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18914        synchronized (this) {
18915            mSuppressResizeConfigChanges = suppress;
18916        }
18917    }
18918
18919    @Override
18920    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18921        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18922        if (fromStackId == HOME_STACK_ID) {
18923            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18924        }
18925        synchronized (this) {
18926            final long origId = Binder.clearCallingIdentity();
18927            try {
18928                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18929            } finally {
18930                Binder.restoreCallingIdentity(origId);
18931            }
18932        }
18933    }
18934
18935    @Override
18936    public void updatePersistentConfiguration(Configuration values) {
18937        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18938                "updateConfiguration()");
18939        enforceWriteSettingsPermission("updateConfiguration()");
18940        if (values == null) {
18941            throw new NullPointerException("Configuration must not be null");
18942        }
18943
18944        int userId = UserHandle.getCallingUserId();
18945
18946        synchronized(this) {
18947            updatePersistentConfigurationLocked(values, userId);
18948        }
18949    }
18950
18951    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18952        final long origId = Binder.clearCallingIdentity();
18953        try {
18954            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18955        } finally {
18956            Binder.restoreCallingIdentity(origId);
18957        }
18958    }
18959
18960    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18961        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18962                FONT_SCALE, 1.0f, userId);
18963        if (mConfiguration.fontScale != scaleFactor) {
18964            final Configuration configuration = mWindowManager.computeNewConfiguration();
18965            configuration.fontScale = scaleFactor;
18966            synchronized (this) {
18967                updatePersistentConfigurationLocked(configuration, userId);
18968            }
18969        }
18970    }
18971
18972    private void enforceWriteSettingsPermission(String func) {
18973        int uid = Binder.getCallingUid();
18974        if (uid == Process.ROOT_UID) {
18975            return;
18976        }
18977
18978        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18979                Settings.getPackageNameForUid(mContext, uid), false)) {
18980            return;
18981        }
18982
18983        String msg = "Permission Denial: " + func + " from pid="
18984                + Binder.getCallingPid()
18985                + ", uid=" + uid
18986                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18987        Slog.w(TAG, msg);
18988        throw new SecurityException(msg);
18989    }
18990
18991    public void updateConfiguration(Configuration values) {
18992        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18993                "updateConfiguration()");
18994
18995        synchronized(this) {
18996            if (values == null && mWindowManager != null) {
18997                // sentinel: fetch the current configuration from the window manager
18998                values = mWindowManager.computeNewConfiguration();
18999            }
19000
19001            if (mWindowManager != null) {
19002                mProcessList.applyDisplaySize(mWindowManager);
19003            }
19004
19005            final long origId = Binder.clearCallingIdentity();
19006            if (values != null) {
19007                Settings.System.clearConfiguration(values);
19008            }
19009            updateConfigurationLocked(values, null, false);
19010            Binder.restoreCallingIdentity(origId);
19011        }
19012    }
19013
19014    void updateUserConfigurationLocked() {
19015        Configuration configuration = new Configuration(mConfiguration);
19016        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19017                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
19018        updateConfigurationLocked(configuration, null, false);
19019    }
19020
19021    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19022            boolean initLocale) {
19023        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19024    }
19025
19026    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19027            boolean initLocale, boolean deferResume) {
19028        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19029        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19030                UserHandle.USER_NULL, deferResume);
19031    }
19032
19033    // To cache the list of supported system locales
19034    private String[] mSupportedSystemLocales = null;
19035
19036    /**
19037     * Do either or both things: (1) change the current configuration, and (2)
19038     * make sure the given activity is running with the (now) current
19039     * configuration.  Returns true if the activity has been left running, or
19040     * false if <var>starting</var> is being destroyed to match the new
19041     * configuration.
19042     *
19043     * @param userId is only used when persistent parameter is set to true to persist configuration
19044     *               for that particular user
19045     */
19046    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19047            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19048        int changes = 0;
19049
19050        if (mWindowManager != null) {
19051            mWindowManager.deferSurfaceLayout();
19052        }
19053        if (values != null) {
19054            Configuration newConfig = new Configuration(mConfiguration);
19055            changes = newConfig.updateFrom(values);
19056            if (changes != 0) {
19057                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19058                        "Updating configuration to: " + values);
19059
19060                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19061
19062                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19063                    final LocaleList locales = values.getLocales();
19064                    int bestLocaleIndex = 0;
19065                    if (locales.size() > 1) {
19066                        if (mSupportedSystemLocales == null) {
19067                            mSupportedSystemLocales =
19068                                    Resources.getSystem().getAssets().getLocales();
19069                        }
19070                        bestLocaleIndex = Math.max(0,
19071                                locales.getFirstMatchIndex(mSupportedSystemLocales));
19072                    }
19073                    SystemProperties.set("persist.sys.locale",
19074                            locales.get(bestLocaleIndex).toLanguageTag());
19075                    LocaleList.setDefault(locales, bestLocaleIndex);
19076                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19077                            locales.get(bestLocaleIndex)));
19078                }
19079
19080                mConfigurationSeq++;
19081                if (mConfigurationSeq <= 0) {
19082                    mConfigurationSeq = 1;
19083                }
19084                newConfig.seq = mConfigurationSeq;
19085                mConfiguration = newConfig;
19086                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19087                mUsageStatsService.reportConfigurationChange(newConfig,
19088                        mUserController.getCurrentUserIdLocked());
19089                //mUsageStatsService.noteStartConfig(newConfig);
19090
19091                final Configuration configCopy = new Configuration(mConfiguration);
19092
19093                // TODO: If our config changes, should we auto dismiss any currently
19094                // showing dialogs?
19095                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19096
19097                AttributeCache ac = AttributeCache.instance();
19098                if (ac != null) {
19099                    ac.updateConfiguration(configCopy);
19100                }
19101
19102                // Make sure all resources in our process are updated
19103                // right now, so that anyone who is going to retrieve
19104                // resource values after we return will be sure to get
19105                // the new ones.  This is especially important during
19106                // boot, where the first config change needs to guarantee
19107                // all resources have that config before following boot
19108                // code is executed.
19109                mSystemThread.applyConfigurationToResources(configCopy);
19110
19111                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19112                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19113                    msg.obj = new Configuration(configCopy);
19114                    msg.arg1 = userId;
19115                    mHandler.sendMessage(msg);
19116                }
19117
19118                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19119                if (isDensityChange) {
19120                    // Reset the unsupported display size dialog.
19121                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19122
19123                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19124                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19125                }
19126
19127                for (int i=mLruProcesses.size()-1; i>=0; i--) {
19128                    ProcessRecord app = mLruProcesses.get(i);
19129                    try {
19130                        if (app.thread != null) {
19131                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19132                                    + app.processName + " new config " + mConfiguration);
19133                            app.thread.scheduleConfigurationChanged(configCopy);
19134                        }
19135                    } catch (Exception e) {
19136                    }
19137                }
19138                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19139                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19140                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
19141                        | Intent.FLAG_RECEIVER_FOREGROUND);
19142                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19143                        null, AppOpsManager.OP_NONE, null, false, false,
19144                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19145                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19146                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19147                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19148	            if (initLocale || !mProcessesReady) {
19149                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19150                    }
19151                    broadcastIntentLocked(null, null, intent,
19152                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19153                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19154                }
19155            }
19156            // Update the configuration with WM first and check if any of the stacks need to be
19157            // resized due to the configuration change. If so, resize the stacks now and do any
19158            // relaunches if necessary. This way we don't need to relaunch again below in
19159            // ensureActivityConfigurationLocked().
19160            if (mWindowManager != null) {
19161                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19162                if (resizedStacks != null) {
19163                    for (int stackId : resizedStacks) {
19164                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19165                        mStackSupervisor.resizeStackLocked(
19166                                stackId, newBounds, null, null, false, false, deferResume);
19167                    }
19168                }
19169            }
19170        }
19171
19172        boolean kept = true;
19173        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19174        // mainStack is null during startup.
19175        if (mainStack != null) {
19176            if (changes != 0 && starting == null) {
19177                // If the configuration changed, and the caller is not already
19178                // in the process of starting an activity, then find the top
19179                // activity to check if its configuration needs to change.
19180                starting = mainStack.topRunningActivityLocked();
19181            }
19182
19183            if (starting != null) {
19184                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19185                // And we need to make sure at this point that all other activities
19186                // are made visible with the correct configuration.
19187                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19188                        !PRESERVE_WINDOWS);
19189            }
19190        }
19191        if (mWindowManager != null) {
19192            mWindowManager.continueSurfaceLayout();
19193        }
19194        return kept;
19195    }
19196
19197    /**
19198     * Decide based on the configuration whether we should shouw the ANR,
19199     * crash, etc dialogs.  The idea is that if there is no affordence to
19200     * press the on-screen buttons, or the user experience would be more
19201     * greatly impacted than the crash itself, we shouldn't show the dialog.
19202     *
19203     * A thought: SystemUI might also want to get told about this, the Power
19204     * dialog / global actions also might want different behaviors.
19205     */
19206    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19207        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19208                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19209                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19210        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19211        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19212                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19213        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19214    }
19215
19216    @Override
19217    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19218        synchronized (this) {
19219            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19220            if (srec != null) {
19221                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19222            }
19223        }
19224        return false;
19225    }
19226
19227    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19228            Intent resultData) {
19229
19230        synchronized (this) {
19231            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19232            if (r != null) {
19233                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19234            }
19235            return false;
19236        }
19237    }
19238
19239    public int getLaunchedFromUid(IBinder activityToken) {
19240        ActivityRecord srec;
19241        synchronized (this) {
19242            srec = ActivityRecord.forTokenLocked(activityToken);
19243        }
19244        if (srec == null) {
19245            return -1;
19246        }
19247        return srec.launchedFromUid;
19248    }
19249
19250    public String getLaunchedFromPackage(IBinder activityToken) {
19251        ActivityRecord srec;
19252        synchronized (this) {
19253            srec = ActivityRecord.forTokenLocked(activityToken);
19254        }
19255        if (srec == null) {
19256            return null;
19257        }
19258        return srec.launchedFromPackage;
19259    }
19260
19261    // =========================================================
19262    // LIFETIME MANAGEMENT
19263    // =========================================================
19264
19265    // Returns whether the app is receiving broadcast.
19266    // If receiving, fetch all broadcast queues which the app is
19267    // the current [or imminent] receiver on.
19268    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19269            ArraySet<BroadcastQueue> receivingQueues) {
19270        if (!app.curReceivers.isEmpty()) {
19271            for (BroadcastRecord r : app.curReceivers) {
19272                receivingQueues.add(r.queue);
19273            }
19274            return true;
19275        }
19276
19277        // It's not the current receiver, but it might be starting up to become one
19278        for (BroadcastQueue queue : mBroadcastQueues) {
19279            final BroadcastRecord r = queue.mPendingBroadcast;
19280            if (r != null && r.curApp == app) {
19281                // found it; report which queue it's in
19282                receivingQueues.add(queue);
19283            }
19284        }
19285
19286        return !receivingQueues.isEmpty();
19287    }
19288
19289    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19290            int targetUid, ComponentName targetComponent, String targetProcess) {
19291        if (!mTrackingAssociations) {
19292            return null;
19293        }
19294        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19295                = mAssociations.get(targetUid);
19296        if (components == null) {
19297            components = new ArrayMap<>();
19298            mAssociations.put(targetUid, components);
19299        }
19300        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19301        if (sourceUids == null) {
19302            sourceUids = new SparseArray<>();
19303            components.put(targetComponent, sourceUids);
19304        }
19305        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19306        if (sourceProcesses == null) {
19307            sourceProcesses = new ArrayMap<>();
19308            sourceUids.put(sourceUid, sourceProcesses);
19309        }
19310        Association ass = sourceProcesses.get(sourceProcess);
19311        if (ass == null) {
19312            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19313                    targetProcess);
19314            sourceProcesses.put(sourceProcess, ass);
19315        }
19316        ass.mCount++;
19317        ass.mNesting++;
19318        if (ass.mNesting == 1) {
19319            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19320            ass.mLastState = sourceState;
19321        }
19322        return ass;
19323    }
19324
19325    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19326            ComponentName targetComponent) {
19327        if (!mTrackingAssociations) {
19328            return;
19329        }
19330        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19331                = mAssociations.get(targetUid);
19332        if (components == null) {
19333            return;
19334        }
19335        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19336        if (sourceUids == null) {
19337            return;
19338        }
19339        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19340        if (sourceProcesses == null) {
19341            return;
19342        }
19343        Association ass = sourceProcesses.get(sourceProcess);
19344        if (ass == null || ass.mNesting <= 0) {
19345            return;
19346        }
19347        ass.mNesting--;
19348        if (ass.mNesting == 0) {
19349            long uptime = SystemClock.uptimeMillis();
19350            ass.mTime += uptime - ass.mStartTime;
19351            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19352                    += uptime - ass.mLastStateUptime;
19353            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19354        }
19355    }
19356
19357    private void noteUidProcessState(final int uid, final int state) {
19358        mBatteryStatsService.noteUidProcessState(uid, state);
19359        if (mTrackingAssociations) {
19360            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19361                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19362                        = mAssociations.valueAt(i1);
19363                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19364                    SparseArray<ArrayMap<String, Association>> sourceUids
19365                            = targetComponents.valueAt(i2);
19366                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19367                    if (sourceProcesses != null) {
19368                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19369                            Association ass = sourceProcesses.valueAt(i4);
19370                            if (ass.mNesting >= 1) {
19371                                // currently associated
19372                                long uptime = SystemClock.uptimeMillis();
19373                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19374                                        += uptime - ass.mLastStateUptime;
19375                                ass.mLastState = state;
19376                                ass.mLastStateUptime = uptime;
19377                            }
19378                        }
19379                    }
19380                }
19381            }
19382        }
19383    }
19384
19385    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19386            boolean doingAll, long now) {
19387        if (mAdjSeq == app.adjSeq) {
19388            // This adjustment has already been computed.
19389            return app.curRawAdj;
19390        }
19391
19392        if (app.thread == null) {
19393            app.adjSeq = mAdjSeq;
19394            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19395            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19396            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19397        }
19398
19399        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19400        app.adjSource = null;
19401        app.adjTarget = null;
19402        app.empty = false;
19403        app.cached = false;
19404
19405        final int activitiesSize = app.activities.size();
19406
19407        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19408            // The max adjustment doesn't allow this app to be anything
19409            // below foreground, so it is not worth doing work for it.
19410            app.adjType = "fixed";
19411            app.adjSeq = mAdjSeq;
19412            app.curRawAdj = app.maxAdj;
19413            app.foregroundActivities = false;
19414            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19415            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19416            // System processes can do UI, and when they do we want to have
19417            // them trim their memory after the user leaves the UI.  To
19418            // facilitate this, here we need to determine whether or not it
19419            // is currently showing UI.
19420            app.systemNoUi = true;
19421            if (app == TOP_APP) {
19422                app.systemNoUi = false;
19423                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19424                app.adjType = "pers-top-activity";
19425            } else if (app.hasTopUi) {
19426                app.systemNoUi = false;
19427                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19428                app.adjType = "pers-top-ui";
19429            } else if (activitiesSize > 0) {
19430                for (int j = 0; j < activitiesSize; j++) {
19431                    final ActivityRecord r = app.activities.get(j);
19432                    if (r.visible) {
19433                        app.systemNoUi = false;
19434                    }
19435                }
19436            }
19437            if (!app.systemNoUi) {
19438                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19439            }
19440            return (app.curAdj=app.maxAdj);
19441        }
19442
19443        app.systemNoUi = false;
19444
19445        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19446
19447        // Determine the importance of the process, starting with most
19448        // important to least, and assign an appropriate OOM adjustment.
19449        int adj;
19450        int schedGroup;
19451        int procState;
19452        boolean foregroundActivities = false;
19453        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19454        if (app == TOP_APP) {
19455            // The last app on the list is the foreground app.
19456            adj = ProcessList.FOREGROUND_APP_ADJ;
19457            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19458            app.adjType = "top-activity";
19459            foregroundActivities = true;
19460            procState = PROCESS_STATE_CUR_TOP;
19461        } else if (app.instrumentationClass != null) {
19462            // Don't want to kill running instrumentation.
19463            adj = ProcessList.FOREGROUND_APP_ADJ;
19464            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19465            app.adjType = "instrumentation";
19466            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19467        } else if (isReceivingBroadcastLocked(app, queues)) {
19468            // An app that is currently receiving a broadcast also
19469            // counts as being in the foreground for OOM killer purposes.
19470            // It's placed in a sched group based on the nature of the
19471            // broadcast as reflected by which queue it's active in.
19472            adj = ProcessList.FOREGROUND_APP_ADJ;
19473            schedGroup = (queues.contains(mFgBroadcastQueue))
19474                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19475            app.adjType = "broadcast";
19476            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19477        } else if (app.executingServices.size() > 0) {
19478            // An app that is currently executing a service callback also
19479            // counts as being in the foreground.
19480            adj = ProcessList.FOREGROUND_APP_ADJ;
19481            schedGroup = app.execServicesFg ?
19482                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19483            app.adjType = "exec-service";
19484            procState = ActivityManager.PROCESS_STATE_SERVICE;
19485            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19486        } else {
19487            // As far as we know the process is empty.  We may change our mind later.
19488            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19489            // At this point we don't actually know the adjustment.  Use the cached adj
19490            // value that the caller wants us to.
19491            adj = cachedAdj;
19492            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19493            app.cached = true;
19494            app.empty = true;
19495            app.adjType = "cch-empty";
19496        }
19497
19498        // Examine all activities if not already foreground.
19499        if (!foregroundActivities && activitiesSize > 0) {
19500            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19501            for (int j = 0; j < activitiesSize; j++) {
19502                final ActivityRecord r = app.activities.get(j);
19503                if (r.app != app) {
19504                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19505                            + " instead of expected " + app);
19506                    if (r.app == null || (r.app.uid == app.uid)) {
19507                        // Only fix things up when they look sane
19508                        r.app = app;
19509                    } else {
19510                        continue;
19511                    }
19512                }
19513                if (r.visible) {
19514                    // App has a visible activity; only upgrade adjustment.
19515                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19516                        adj = ProcessList.VISIBLE_APP_ADJ;
19517                        app.adjType = "visible";
19518                    }
19519                    if (procState > PROCESS_STATE_CUR_TOP) {
19520                        procState = PROCESS_STATE_CUR_TOP;
19521                    }
19522                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19523                    app.cached = false;
19524                    app.empty = false;
19525                    foregroundActivities = true;
19526                    if (r.task != null && minLayer > 0) {
19527                        final int layer = r.task.mLayerRank;
19528                        if (layer >= 0 && minLayer > layer) {
19529                            minLayer = layer;
19530                        }
19531                    }
19532                    break;
19533                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19534                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19535                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19536                        app.adjType = "pausing";
19537                    }
19538                    if (procState > PROCESS_STATE_CUR_TOP) {
19539                        procState = PROCESS_STATE_CUR_TOP;
19540                    }
19541                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19542                    app.cached = false;
19543                    app.empty = false;
19544                    foregroundActivities = true;
19545                } else if (r.state == ActivityState.STOPPING) {
19546                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19547                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19548                        app.adjType = "stopping";
19549                    }
19550                    // For the process state, we will at this point consider the
19551                    // process to be cached.  It will be cached either as an activity
19552                    // or empty depending on whether the activity is finishing.  We do
19553                    // this so that we can treat the process as cached for purposes of
19554                    // memory trimming (determing current memory level, trim command to
19555                    // send to process) since there can be an arbitrary number of stopping
19556                    // processes and they should soon all go into the cached state.
19557                    if (!r.finishing) {
19558                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19559                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19560                        }
19561                    }
19562                    app.cached = false;
19563                    app.empty = false;
19564                    foregroundActivities = true;
19565                } else {
19566                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19567                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19568                        app.adjType = "cch-act";
19569                    }
19570                }
19571            }
19572            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19573                adj += minLayer;
19574            }
19575        }
19576
19577        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19578                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19579            if (app.foregroundServices) {
19580                // The user is aware of this app, so make it visible.
19581                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19582                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19583                app.cached = false;
19584                app.adjType = "fg-service";
19585                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19586            } else if (app.forcingToForeground != null) {
19587                // The user is aware of this app, so make it visible.
19588                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19589                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19590                app.cached = false;
19591                app.adjType = "force-fg";
19592                app.adjSource = app.forcingToForeground;
19593                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19594            }
19595        }
19596
19597        if (app == mHeavyWeightProcess) {
19598            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19599                // We don't want to kill the current heavy-weight process.
19600                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19601                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19602                app.cached = false;
19603                app.adjType = "heavy";
19604            }
19605            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19606                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19607            }
19608        }
19609
19610        if (app == mHomeProcess) {
19611            if (adj > ProcessList.HOME_APP_ADJ) {
19612                // This process is hosting what we currently consider to be the
19613                // home app, so we don't want to let it go into the background.
19614                adj = ProcessList.HOME_APP_ADJ;
19615                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19616                app.cached = false;
19617                app.adjType = "home";
19618            }
19619            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19620                procState = ActivityManager.PROCESS_STATE_HOME;
19621            }
19622        }
19623
19624        if (app == mPreviousProcess && app.activities.size() > 0) {
19625            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19626                // This was the previous process that showed UI to the user.
19627                // We want to try to keep it around more aggressively, to give
19628                // a good experience around switching between two apps.
19629                adj = ProcessList.PREVIOUS_APP_ADJ;
19630                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19631                app.cached = false;
19632                app.adjType = "previous";
19633            }
19634            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19635                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19636            }
19637        }
19638
19639        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19640                + " reason=" + app.adjType);
19641
19642        // By default, we use the computed adjustment.  It may be changed if
19643        // there are applications dependent on our services or providers, but
19644        // this gives us a baseline and makes sure we don't get into an
19645        // infinite recursion.
19646        app.adjSeq = mAdjSeq;
19647        app.curRawAdj = adj;
19648        app.hasStartedServices = false;
19649
19650        if (mBackupTarget != null && app == mBackupTarget.app) {
19651            // If possible we want to avoid killing apps while they're being backed up
19652            if (adj > ProcessList.BACKUP_APP_ADJ) {
19653                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19654                adj = ProcessList.BACKUP_APP_ADJ;
19655                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19656                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19657                }
19658                app.adjType = "backup";
19659                app.cached = false;
19660            }
19661            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19662                procState = ActivityManager.PROCESS_STATE_BACKUP;
19663            }
19664        }
19665
19666        boolean mayBeTop = false;
19667
19668        for (int is = app.services.size()-1;
19669                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19670                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19671                        || procState > ActivityManager.PROCESS_STATE_TOP);
19672                is--) {
19673            ServiceRecord s = app.services.valueAt(is);
19674            if (s.startRequested) {
19675                app.hasStartedServices = true;
19676                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19677                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19678                }
19679                if (app.hasShownUi && app != mHomeProcess) {
19680                    // If this process has shown some UI, let it immediately
19681                    // go to the LRU list because it may be pretty heavy with
19682                    // UI stuff.  We'll tag it with a label just to help
19683                    // debug and understand what is going on.
19684                    if (adj > ProcessList.SERVICE_ADJ) {
19685                        app.adjType = "cch-started-ui-services";
19686                    }
19687                } else {
19688                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19689                        // This service has seen some activity within
19690                        // recent memory, so we will keep its process ahead
19691                        // of the background processes.
19692                        if (adj > ProcessList.SERVICE_ADJ) {
19693                            adj = ProcessList.SERVICE_ADJ;
19694                            app.adjType = "started-services";
19695                            app.cached = false;
19696                        }
19697                    }
19698                    // If we have let the service slide into the background
19699                    // state, still have some text describing what it is doing
19700                    // even though the service no longer has an impact.
19701                    if (adj > ProcessList.SERVICE_ADJ) {
19702                        app.adjType = "cch-started-services";
19703                    }
19704                }
19705            }
19706
19707            for (int conni = s.connections.size()-1;
19708                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19709                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19710                            || procState > ActivityManager.PROCESS_STATE_TOP);
19711                    conni--) {
19712                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19713                for (int i = 0;
19714                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19715                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19716                                || procState > ActivityManager.PROCESS_STATE_TOP);
19717                        i++) {
19718                    // XXX should compute this based on the max of
19719                    // all connected clients.
19720                    ConnectionRecord cr = clist.get(i);
19721                    if (cr.binding.client == app) {
19722                        // Binding to ourself is not interesting.
19723                        continue;
19724                    }
19725
19726                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19727                        ProcessRecord client = cr.binding.client;
19728                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19729                                TOP_APP, doingAll, now);
19730                        int clientProcState = client.curProcState;
19731                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19732                            // If the other app is cached for any reason, for purposes here
19733                            // we are going to consider it empty.  The specific cached state
19734                            // doesn't propagate except under certain conditions.
19735                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19736                        }
19737                        String adjType = null;
19738                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19739                            // Not doing bind OOM management, so treat
19740                            // this guy more like a started service.
19741                            if (app.hasShownUi && app != mHomeProcess) {
19742                                // If this process has shown some UI, let it immediately
19743                                // go to the LRU list because it may be pretty heavy with
19744                                // UI stuff.  We'll tag it with a label just to help
19745                                // debug and understand what is going on.
19746                                if (adj > clientAdj) {
19747                                    adjType = "cch-bound-ui-services";
19748                                }
19749                                app.cached = false;
19750                                clientAdj = adj;
19751                                clientProcState = procState;
19752                            } else {
19753                                if (now >= (s.lastActivity
19754                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19755                                    // This service has not seen activity within
19756                                    // recent memory, so allow it to drop to the
19757                                    // LRU list if there is no other reason to keep
19758                                    // it around.  We'll also tag it with a label just
19759                                    // to help debug and undertand what is going on.
19760                                    if (adj > clientAdj) {
19761                                        adjType = "cch-bound-services";
19762                                    }
19763                                    clientAdj = adj;
19764                                }
19765                            }
19766                        }
19767                        if (adj > clientAdj) {
19768                            // If this process has recently shown UI, and
19769                            // the process that is binding to it is less
19770                            // important than being visible, then we don't
19771                            // care about the binding as much as we care
19772                            // about letting this process get into the LRU
19773                            // list to be killed and restarted if needed for
19774                            // memory.
19775                            if (app.hasShownUi && app != mHomeProcess
19776                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19777                                adjType = "cch-bound-ui-services";
19778                            } else {
19779                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19780                                        |Context.BIND_IMPORTANT)) != 0) {
19781                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19782                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19783                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19784                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19785                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19786                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19787                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19788                                    adj = clientAdj;
19789                                } else {
19790                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19791                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19792                                    }
19793                                }
19794                                if (!client.cached) {
19795                                    app.cached = false;
19796                                }
19797                                adjType = "service";
19798                            }
19799                        }
19800                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19801                            // This will treat important bound services identically to
19802                            // the top app, which may behave differently than generic
19803                            // foreground work.
19804                            if (client.curSchedGroup > schedGroup) {
19805                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19806                                    schedGroup = client.curSchedGroup;
19807                                } else {
19808                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19809                                }
19810                            }
19811                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19812                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19813                                    // Special handling of clients who are in the top state.
19814                                    // We *may* want to consider this process to be in the
19815                                    // top state as well, but only if there is not another
19816                                    // reason for it to be running.  Being on the top is a
19817                                    // special state, meaning you are specifically running
19818                                    // for the current top app.  If the process is already
19819                                    // running in the background for some other reason, it
19820                                    // is more important to continue considering it to be
19821                                    // in the background state.
19822                                    mayBeTop = true;
19823                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19824                                } else {
19825                                    // Special handling for above-top states (persistent
19826                                    // processes).  These should not bring the current process
19827                                    // into the top state, since they are not on top.  Instead
19828                                    // give them the best state after that.
19829                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19830                                        clientProcState =
19831                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19832                                    } else if (mWakefulness
19833                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19834                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19835                                                    != 0) {
19836                                        clientProcState =
19837                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19838                                    } else {
19839                                        clientProcState =
19840                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19841                                    }
19842                                }
19843                            }
19844                        } else {
19845                            if (clientProcState <
19846                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19847                                clientProcState =
19848                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19849                            }
19850                        }
19851                        if (procState > clientProcState) {
19852                            procState = clientProcState;
19853                        }
19854                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19855                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19856                            app.pendingUiClean = true;
19857                        }
19858                        if (adjType != null) {
19859                            app.adjType = adjType;
19860                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19861                                    .REASON_SERVICE_IN_USE;
19862                            app.adjSource = cr.binding.client;
19863                            app.adjSourceProcState = clientProcState;
19864                            app.adjTarget = s.name;
19865                        }
19866                    }
19867                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19868                        app.treatLikeActivity = true;
19869                    }
19870                    final ActivityRecord a = cr.activity;
19871                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19872                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19873                            (a.visible || a.state == ActivityState.RESUMED ||
19874                             a.state == ActivityState.PAUSING)) {
19875                            adj = ProcessList.FOREGROUND_APP_ADJ;
19876                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19877                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19878                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19879                                } else {
19880                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19881                                }
19882                            }
19883                            app.cached = false;
19884                            app.adjType = "service";
19885                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19886                                    .REASON_SERVICE_IN_USE;
19887                            app.adjSource = a;
19888                            app.adjSourceProcState = procState;
19889                            app.adjTarget = s.name;
19890                        }
19891                    }
19892                }
19893            }
19894        }
19895
19896        for (int provi = app.pubProviders.size()-1;
19897                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19898                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19899                        || procState > ActivityManager.PROCESS_STATE_TOP);
19900                provi--) {
19901            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19902            for (int i = cpr.connections.size()-1;
19903                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19904                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19905                            || procState > ActivityManager.PROCESS_STATE_TOP);
19906                    i--) {
19907                ContentProviderConnection conn = cpr.connections.get(i);
19908                ProcessRecord client = conn.client;
19909                if (client == app) {
19910                    // Being our own client is not interesting.
19911                    continue;
19912                }
19913                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19914                int clientProcState = client.curProcState;
19915                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19916                    // If the other app is cached for any reason, for purposes here
19917                    // we are going to consider it empty.
19918                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19919                }
19920                if (adj > clientAdj) {
19921                    if (app.hasShownUi && app != mHomeProcess
19922                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19923                        app.adjType = "cch-ui-provider";
19924                    } else {
19925                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19926                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19927                        app.adjType = "provider";
19928                    }
19929                    app.cached &= client.cached;
19930                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19931                            .REASON_PROVIDER_IN_USE;
19932                    app.adjSource = client;
19933                    app.adjSourceProcState = clientProcState;
19934                    app.adjTarget = cpr.name;
19935                }
19936                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19937                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19938                        // Special handling of clients who are in the top state.
19939                        // We *may* want to consider this process to be in the
19940                        // top state as well, but only if there is not another
19941                        // reason for it to be running.  Being on the top is a
19942                        // special state, meaning you are specifically running
19943                        // for the current top app.  If the process is already
19944                        // running in the background for some other reason, it
19945                        // is more important to continue considering it to be
19946                        // in the background state.
19947                        mayBeTop = true;
19948                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19949                    } else {
19950                        // Special handling for above-top states (persistent
19951                        // processes).  These should not bring the current process
19952                        // into the top state, since they are not on top.  Instead
19953                        // give them the best state after that.
19954                        clientProcState =
19955                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19956                    }
19957                }
19958                if (procState > clientProcState) {
19959                    procState = clientProcState;
19960                }
19961                if (client.curSchedGroup > schedGroup) {
19962                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19963                }
19964            }
19965            // If the provider has external (non-framework) process
19966            // dependencies, ensure that its adjustment is at least
19967            // FOREGROUND_APP_ADJ.
19968            if (cpr.hasExternalProcessHandles()) {
19969                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19970                    adj = ProcessList.FOREGROUND_APP_ADJ;
19971                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19972                    app.cached = false;
19973                    app.adjType = "provider";
19974                    app.adjTarget = cpr.name;
19975                }
19976                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19977                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19978                }
19979            }
19980        }
19981
19982        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19983            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19984                adj = ProcessList.PREVIOUS_APP_ADJ;
19985                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19986                app.cached = false;
19987                app.adjType = "provider";
19988            }
19989            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19990                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19991            }
19992        }
19993
19994        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19995            // A client of one of our services or providers is in the top state.  We
19996            // *may* want to be in the top state, but not if we are already running in
19997            // the background for some other reason.  For the decision here, we are going
19998            // to pick out a few specific states that we want to remain in when a client
19999            // is top (states that tend to be longer-term) and otherwise allow it to go
20000            // to the top state.
20001            switch (procState) {
20002                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20003                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20004                case ActivityManager.PROCESS_STATE_SERVICE:
20005                    // These all are longer-term states, so pull them up to the top
20006                    // of the background states, but not all the way to the top state.
20007                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20008                    break;
20009                default:
20010                    // Otherwise, top is a better choice, so take it.
20011                    procState = ActivityManager.PROCESS_STATE_TOP;
20012                    break;
20013            }
20014        }
20015
20016        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20017            if (app.hasClientActivities) {
20018                // This is a cached process, but with client activities.  Mark it so.
20019                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20020                app.adjType = "cch-client-act";
20021            } else if (app.treatLikeActivity) {
20022                // This is a cached process, but somebody wants us to treat it like it has
20023                // an activity, okay!
20024                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20025                app.adjType = "cch-as-act";
20026            }
20027        }
20028
20029        if (adj == ProcessList.SERVICE_ADJ) {
20030            if (doingAll) {
20031                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20032                mNewNumServiceProcs++;
20033                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20034                if (!app.serviceb) {
20035                    // This service isn't far enough down on the LRU list to
20036                    // normally be a B service, but if we are low on RAM and it
20037                    // is large we want to force it down since we would prefer to
20038                    // keep launcher over it.
20039                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20040                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20041                        app.serviceHighRam = true;
20042                        app.serviceb = true;
20043                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20044                    } else {
20045                        mNewNumAServiceProcs++;
20046                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20047                    }
20048                } else {
20049                    app.serviceHighRam = false;
20050                }
20051            }
20052            if (app.serviceb) {
20053                adj = ProcessList.SERVICE_B_ADJ;
20054            }
20055        }
20056
20057        app.curRawAdj = adj;
20058
20059        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20060        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20061        if (adj > app.maxAdj) {
20062            adj = app.maxAdj;
20063            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20064                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20065            }
20066        }
20067
20068        // Do final modification to adj.  Everything we do between here and applying
20069        // the final setAdj must be done in this function, because we will also use
20070        // it when computing the final cached adj later.  Note that we don't need to
20071        // worry about this for max adj above, since max adj will always be used to
20072        // keep it out of the cached vaues.
20073        app.curAdj = app.modifyRawOomAdj(adj);
20074        app.curSchedGroup = schedGroup;
20075        app.curProcState = procState;
20076        app.foregroundActivities = foregroundActivities;
20077
20078        return app.curRawAdj;
20079    }
20080
20081    /**
20082     * Record new PSS sample for a process.
20083     */
20084    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20085            long now) {
20086        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20087                swapPss * 1024);
20088        proc.lastPssTime = now;
20089        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20090        if (DEBUG_PSS) Slog.d(TAG_PSS,
20091                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20092                + " state=" + ProcessList.makeProcStateString(procState));
20093        if (proc.initialIdlePss == 0) {
20094            proc.initialIdlePss = pss;
20095        }
20096        proc.lastPss = pss;
20097        proc.lastSwapPss = swapPss;
20098        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20099            proc.lastCachedPss = pss;
20100            proc.lastCachedSwapPss = swapPss;
20101        }
20102
20103        final SparseArray<Pair<Long, String>> watchUids
20104                = mMemWatchProcesses.getMap().get(proc.processName);
20105        Long check = null;
20106        if (watchUids != null) {
20107            Pair<Long, String> val = watchUids.get(proc.uid);
20108            if (val == null) {
20109                val = watchUids.get(0);
20110            }
20111            if (val != null) {
20112                check = val.first;
20113            }
20114        }
20115        if (check != null) {
20116            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20117                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20118                if (!isDebuggable) {
20119                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20120                        isDebuggable = true;
20121                    }
20122                }
20123                if (isDebuggable) {
20124                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20125                    final ProcessRecord myProc = proc;
20126                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20127                    mMemWatchDumpProcName = proc.processName;
20128                    mMemWatchDumpFile = heapdumpFile.toString();
20129                    mMemWatchDumpPid = proc.pid;
20130                    mMemWatchDumpUid = proc.uid;
20131                    BackgroundThread.getHandler().post(new Runnable() {
20132                        @Override
20133                        public void run() {
20134                            revokeUriPermission(ActivityThread.currentActivityThread()
20135                                            .getApplicationThread(),
20136                                    DumpHeapActivity.JAVA_URI,
20137                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20138                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20139                                    UserHandle.myUserId());
20140                            ParcelFileDescriptor fd = null;
20141                            try {
20142                                heapdumpFile.delete();
20143                                fd = ParcelFileDescriptor.open(heapdumpFile,
20144                                        ParcelFileDescriptor.MODE_CREATE |
20145                                                ParcelFileDescriptor.MODE_TRUNCATE |
20146                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20147                                                ParcelFileDescriptor.MODE_APPEND);
20148                                IApplicationThread thread = myProc.thread;
20149                                if (thread != null) {
20150                                    try {
20151                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20152                                                "Requesting dump heap from "
20153                                                + myProc + " to " + heapdumpFile);
20154                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20155                                    } catch (RemoteException e) {
20156                                    }
20157                                }
20158                            } catch (FileNotFoundException e) {
20159                                e.printStackTrace();
20160                            } finally {
20161                                if (fd != null) {
20162                                    try {
20163                                        fd.close();
20164                                    } catch (IOException e) {
20165                                    }
20166                                }
20167                            }
20168                        }
20169                    });
20170                } else {
20171                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20172                            + ", but debugging not enabled");
20173                }
20174            }
20175        }
20176    }
20177
20178    /**
20179     * Schedule PSS collection of a process.
20180     */
20181    void requestPssLocked(ProcessRecord proc, int procState) {
20182        if (mPendingPssProcesses.contains(proc)) {
20183            return;
20184        }
20185        if (mPendingPssProcesses.size() == 0) {
20186            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20187        }
20188        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20189        proc.pssProcState = procState;
20190        mPendingPssProcesses.add(proc);
20191    }
20192
20193    /**
20194     * Schedule PSS collection of all processes.
20195     */
20196    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20197        if (!always) {
20198            if (now < (mLastFullPssTime +
20199                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20200                return;
20201            }
20202        }
20203        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20204        mLastFullPssTime = now;
20205        mFullPssPending = true;
20206        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20207        mPendingPssProcesses.clear();
20208        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20209            ProcessRecord app = mLruProcesses.get(i);
20210            if (app.thread == null
20211                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20212                continue;
20213            }
20214            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20215                app.pssProcState = app.setProcState;
20216                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20217                        mTestPssMode, isSleepingLocked(), now);
20218                mPendingPssProcesses.add(app);
20219            }
20220        }
20221        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20222    }
20223
20224    public void setTestPssMode(boolean enabled) {
20225        synchronized (this) {
20226            mTestPssMode = enabled;
20227            if (enabled) {
20228                // Whenever we enable the mode, we want to take a snapshot all of current
20229                // process mem use.
20230                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20231            }
20232        }
20233    }
20234
20235    /**
20236     * Ask a given process to GC right now.
20237     */
20238    final void performAppGcLocked(ProcessRecord app) {
20239        try {
20240            app.lastRequestedGc = SystemClock.uptimeMillis();
20241            if (app.thread != null) {
20242                if (app.reportLowMemory) {
20243                    app.reportLowMemory = false;
20244                    app.thread.scheduleLowMemory();
20245                } else {
20246                    app.thread.processInBackground();
20247                }
20248            }
20249        } catch (Exception e) {
20250            // whatever.
20251        }
20252    }
20253
20254    /**
20255     * Returns true if things are idle enough to perform GCs.
20256     */
20257    private final boolean canGcNowLocked() {
20258        boolean processingBroadcasts = false;
20259        for (BroadcastQueue q : mBroadcastQueues) {
20260            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20261                processingBroadcasts = true;
20262            }
20263        }
20264        return !processingBroadcasts
20265                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20266    }
20267
20268    /**
20269     * Perform GCs on all processes that are waiting for it, but only
20270     * if things are idle.
20271     */
20272    final void performAppGcsLocked() {
20273        final int N = mProcessesToGc.size();
20274        if (N <= 0) {
20275            return;
20276        }
20277        if (canGcNowLocked()) {
20278            while (mProcessesToGc.size() > 0) {
20279                ProcessRecord proc = mProcessesToGc.remove(0);
20280                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20281                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20282                            <= SystemClock.uptimeMillis()) {
20283                        // To avoid spamming the system, we will GC processes one
20284                        // at a time, waiting a few seconds between each.
20285                        performAppGcLocked(proc);
20286                        scheduleAppGcsLocked();
20287                        return;
20288                    } else {
20289                        // It hasn't been long enough since we last GCed this
20290                        // process...  put it in the list to wait for its time.
20291                        addProcessToGcListLocked(proc);
20292                        break;
20293                    }
20294                }
20295            }
20296
20297            scheduleAppGcsLocked();
20298        }
20299    }
20300
20301    /**
20302     * If all looks good, perform GCs on all processes waiting for them.
20303     */
20304    final void performAppGcsIfAppropriateLocked() {
20305        if (canGcNowLocked()) {
20306            performAppGcsLocked();
20307            return;
20308        }
20309        // Still not idle, wait some more.
20310        scheduleAppGcsLocked();
20311    }
20312
20313    /**
20314     * Schedule the execution of all pending app GCs.
20315     */
20316    final void scheduleAppGcsLocked() {
20317        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20318
20319        if (mProcessesToGc.size() > 0) {
20320            // Schedule a GC for the time to the next process.
20321            ProcessRecord proc = mProcessesToGc.get(0);
20322            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20323
20324            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20325            long now = SystemClock.uptimeMillis();
20326            if (when < (now+GC_TIMEOUT)) {
20327                when = now + GC_TIMEOUT;
20328            }
20329            mHandler.sendMessageAtTime(msg, when);
20330        }
20331    }
20332
20333    /**
20334     * Add a process to the array of processes waiting to be GCed.  Keeps the
20335     * list in sorted order by the last GC time.  The process can't already be
20336     * on the list.
20337     */
20338    final void addProcessToGcListLocked(ProcessRecord proc) {
20339        boolean added = false;
20340        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20341            if (mProcessesToGc.get(i).lastRequestedGc <
20342                    proc.lastRequestedGc) {
20343                added = true;
20344                mProcessesToGc.add(i+1, proc);
20345                break;
20346            }
20347        }
20348        if (!added) {
20349            mProcessesToGc.add(0, proc);
20350        }
20351    }
20352
20353    /**
20354     * Set up to ask a process to GC itself.  This will either do it
20355     * immediately, or put it on the list of processes to gc the next
20356     * time things are idle.
20357     */
20358    final void scheduleAppGcLocked(ProcessRecord app) {
20359        long now = SystemClock.uptimeMillis();
20360        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20361            return;
20362        }
20363        if (!mProcessesToGc.contains(app)) {
20364            addProcessToGcListLocked(app);
20365            scheduleAppGcsLocked();
20366        }
20367    }
20368
20369    final void checkExcessivePowerUsageLocked(boolean doKills) {
20370        updateCpuStatsNow();
20371
20372        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20373        boolean doWakeKills = doKills;
20374        boolean doCpuKills = doKills;
20375        if (mLastPowerCheckRealtime == 0) {
20376            doWakeKills = false;
20377        }
20378        if (mLastPowerCheckUptime == 0) {
20379            doCpuKills = false;
20380        }
20381        if (stats.isScreenOn()) {
20382            doWakeKills = false;
20383        }
20384        final long curRealtime = SystemClock.elapsedRealtime();
20385        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20386        final long curUptime = SystemClock.uptimeMillis();
20387        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20388        mLastPowerCheckRealtime = curRealtime;
20389        mLastPowerCheckUptime = curUptime;
20390        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20391            doWakeKills = false;
20392        }
20393        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20394            doCpuKills = false;
20395        }
20396        int i = mLruProcesses.size();
20397        while (i > 0) {
20398            i--;
20399            ProcessRecord app = mLruProcesses.get(i);
20400            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20401                long wtime;
20402                synchronized (stats) {
20403                    wtime = stats.getProcessWakeTime(app.info.uid,
20404                            app.pid, curRealtime);
20405                }
20406                long wtimeUsed = wtime - app.lastWakeTime;
20407                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20408                if (DEBUG_POWER) {
20409                    StringBuilder sb = new StringBuilder(128);
20410                    sb.append("Wake for ");
20411                    app.toShortString(sb);
20412                    sb.append(": over ");
20413                    TimeUtils.formatDuration(realtimeSince, sb);
20414                    sb.append(" used ");
20415                    TimeUtils.formatDuration(wtimeUsed, sb);
20416                    sb.append(" (");
20417                    sb.append((wtimeUsed*100)/realtimeSince);
20418                    sb.append("%)");
20419                    Slog.i(TAG_POWER, sb.toString());
20420                    sb.setLength(0);
20421                    sb.append("CPU for ");
20422                    app.toShortString(sb);
20423                    sb.append(": over ");
20424                    TimeUtils.formatDuration(uptimeSince, sb);
20425                    sb.append(" used ");
20426                    TimeUtils.formatDuration(cputimeUsed, sb);
20427                    sb.append(" (");
20428                    sb.append((cputimeUsed*100)/uptimeSince);
20429                    sb.append("%)");
20430                    Slog.i(TAG_POWER, sb.toString());
20431                }
20432                // If a process has held a wake lock for more
20433                // than 50% of the time during this period,
20434                // that sounds bad.  Kill!
20435                if (doWakeKills && realtimeSince > 0
20436                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20437                    synchronized (stats) {
20438                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20439                                realtimeSince, wtimeUsed);
20440                    }
20441                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20442                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20443                } else if (doCpuKills && uptimeSince > 0
20444                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20445                    synchronized (stats) {
20446                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20447                                uptimeSince, cputimeUsed);
20448                    }
20449                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20450                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20451                } else {
20452                    app.lastWakeTime = wtime;
20453                    app.lastCpuTime = app.curCpuTime;
20454                }
20455            }
20456        }
20457    }
20458
20459    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20460            long nowElapsed) {
20461        boolean success = true;
20462
20463        if (app.curRawAdj != app.setRawAdj) {
20464            app.setRawAdj = app.curRawAdj;
20465        }
20466
20467        int changes = 0;
20468
20469        if (app.curAdj != app.setAdj) {
20470            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20471            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20472                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20473                    + app.adjType);
20474            app.setAdj = app.curAdj;
20475            app.verifiedAdj = ProcessList.INVALID_ADJ;
20476        }
20477
20478        if (app.setSchedGroup != app.curSchedGroup) {
20479            int oldSchedGroup = app.setSchedGroup;
20480            app.setSchedGroup = app.curSchedGroup;
20481            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20482                    "Setting sched group of " + app.processName
20483                    + " to " + app.curSchedGroup);
20484            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20485                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20486                app.kill(app.waitingToKill, true);
20487                success = false;
20488            } else {
20489                int processGroup;
20490                switch (app.curSchedGroup) {
20491                    case ProcessList.SCHED_GROUP_BACKGROUND:
20492                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20493                        break;
20494                    case ProcessList.SCHED_GROUP_TOP_APP:
20495                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20496                        processGroup = Process.THREAD_GROUP_TOP_APP;
20497                        break;
20498                    default:
20499                        processGroup = Process.THREAD_GROUP_DEFAULT;
20500                        break;
20501                }
20502                long oldId = Binder.clearCallingIdentity();
20503                try {
20504                    Process.setProcessGroup(app.pid, processGroup);
20505                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20506                        // do nothing if we already switched to RT
20507                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20508                            // Switch VR thread for app to SCHED_FIFO
20509                            if (mInVrMode && app.vrThreadTid != 0) {
20510                                try {
20511                                    Process.setThreadScheduler(app.vrThreadTid,
20512                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20513                                } catch (IllegalArgumentException e) {
20514                                    // thread died, ignore
20515                                }
20516                            }
20517                            if (mUseFifoUiScheduling) {
20518                                // Switch UI pipeline for app to SCHED_FIFO
20519                                app.savedPriority = Process.getThreadPriority(app.pid);
20520                                try {
20521                                    Process.setThreadScheduler(app.pid,
20522                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20523                                } catch (IllegalArgumentException e) {
20524                                    // thread died, ignore
20525                                }
20526                                if (app.renderThreadTid != 0) {
20527                                    try {
20528                                        Process.setThreadScheduler(app.renderThreadTid,
20529                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20530                                    } catch (IllegalArgumentException e) {
20531                                        // thread died, ignore
20532                                    }
20533                                    if (DEBUG_OOM_ADJ) {
20534                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20535                                            app.renderThreadTid + ") to FIFO");
20536                                    }
20537                                } else {
20538                                    if (DEBUG_OOM_ADJ) {
20539                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20540                                    }
20541                                }
20542                            } else {
20543                                // Boost priority for top app UI and render threads
20544                                Process.setThreadPriority(app.pid, -10);
20545                                if (app.renderThreadTid != 0) {
20546                                    try {
20547                                        Process.setThreadPriority(app.renderThreadTid, -10);
20548                                    } catch (IllegalArgumentException e) {
20549                                        // thread died, ignore
20550                                    }
20551                                }
20552                            }
20553                        }
20554                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20555                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20556                        // Reset VR thread to SCHED_OTHER
20557                        // Safe to do even if we're not in VR mode
20558                        if (app.vrThreadTid != 0) {
20559                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20560                        }
20561                        if (mUseFifoUiScheduling) {
20562                            // Reset UI pipeline to SCHED_OTHER
20563                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20564                            Process.setThreadPriority(app.pid, app.savedPriority);
20565                            if (app.renderThreadTid != 0) {
20566                                Process.setThreadScheduler(app.renderThreadTid,
20567                                    Process.SCHED_OTHER, 0);
20568                                Process.setThreadPriority(app.renderThreadTid, -4);
20569                            }
20570                        } else {
20571                            // Reset priority for top app UI and render threads
20572                            Process.setThreadPriority(app.pid, 0);
20573                            if (app.renderThreadTid != 0) {
20574                                Process.setThreadPriority(app.renderThreadTid, 0);
20575                            }
20576                        }
20577                    }
20578                } catch (Exception e) {
20579                    Slog.w(TAG, "Failed setting process group of " + app.pid
20580                            + " to " + app.curSchedGroup);
20581                    e.printStackTrace();
20582                } finally {
20583                    Binder.restoreCallingIdentity(oldId);
20584                }
20585            }
20586        }
20587        if (app.repForegroundActivities != app.foregroundActivities) {
20588            app.repForegroundActivities = app.foregroundActivities;
20589            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20590        }
20591        if (app.repProcState != app.curProcState) {
20592            app.repProcState = app.curProcState;
20593            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20594            if (app.thread != null) {
20595                try {
20596                    if (false) {
20597                        //RuntimeException h = new RuntimeException("here");
20598                        Slog.i(TAG, "Sending new process state " + app.repProcState
20599                                + " to " + app /*, h*/);
20600                    }
20601                    app.thread.setProcessState(app.repProcState);
20602                } catch (RemoteException e) {
20603                }
20604            }
20605        }
20606        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20607                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20608            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20609                // Experimental code to more aggressively collect pss while
20610                // running test...  the problem is that this tends to collect
20611                // the data right when a process is transitioning between process
20612                // states, which well tend to give noisy data.
20613                long start = SystemClock.uptimeMillis();
20614                long pss = Debug.getPss(app.pid, mTmpLong, null);
20615                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20616                mPendingPssProcesses.remove(app);
20617                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20618                        + " to " + app.curProcState + ": "
20619                        + (SystemClock.uptimeMillis()-start) + "ms");
20620            }
20621            app.lastStateTime = now;
20622            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20623                    mTestPssMode, isSleepingLocked(), now);
20624            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20625                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20626                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20627                    + (app.nextPssTime-now) + ": " + app);
20628        } else {
20629            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20630                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20631                    mTestPssMode)))) {
20632                requestPssLocked(app, app.setProcState);
20633                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20634                        mTestPssMode, isSleepingLocked(), now);
20635            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20636                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20637        }
20638        if (app.setProcState != app.curProcState) {
20639            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20640                    "Proc state change of " + app.processName
20641                            + " to " + app.curProcState);
20642            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20643            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20644            if (setImportant && !curImportant) {
20645                // This app is no longer something we consider important enough to allow to
20646                // use arbitrary amounts of battery power.  Note
20647                // its current wake lock time to later know to kill it if
20648                // it is not behaving well.
20649                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20650                synchronized (stats) {
20651                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20652                            app.pid, nowElapsed);
20653                }
20654                app.lastCpuTime = app.curCpuTime;
20655
20656            }
20657            // Inform UsageStats of important process state change
20658            // Must be called before updating setProcState
20659            maybeUpdateUsageStatsLocked(app, nowElapsed);
20660
20661            app.setProcState = app.curProcState;
20662            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20663                app.notCachedSinceIdle = false;
20664            }
20665            if (!doingAll) {
20666                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20667            } else {
20668                app.procStateChanged = true;
20669            }
20670        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20671                > USAGE_STATS_INTERACTION_INTERVAL) {
20672            // For apps that sit around for a long time in the interactive state, we need
20673            // to report this at least once a day so they don't go idle.
20674            maybeUpdateUsageStatsLocked(app, nowElapsed);
20675        }
20676
20677        if (changes != 0) {
20678            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20679                    "Changes in " + app + ": " + changes);
20680            int i = mPendingProcessChanges.size()-1;
20681            ProcessChangeItem item = null;
20682            while (i >= 0) {
20683                item = mPendingProcessChanges.get(i);
20684                if (item.pid == app.pid) {
20685                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20686                            "Re-using existing item: " + item);
20687                    break;
20688                }
20689                i--;
20690            }
20691            if (i < 0) {
20692                // No existing item in pending changes; need a new one.
20693                final int NA = mAvailProcessChanges.size();
20694                if (NA > 0) {
20695                    item = mAvailProcessChanges.remove(NA-1);
20696                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20697                            "Retrieving available item: " + item);
20698                } else {
20699                    item = new ProcessChangeItem();
20700                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20701                            "Allocating new item: " + item);
20702                }
20703                item.changes = 0;
20704                item.pid = app.pid;
20705                item.uid = app.info.uid;
20706                if (mPendingProcessChanges.size() == 0) {
20707                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20708                            "*** Enqueueing dispatch processes changed!");
20709                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20710                }
20711                mPendingProcessChanges.add(item);
20712            }
20713            item.changes |= changes;
20714            item.processState = app.repProcState;
20715            item.foregroundActivities = app.repForegroundActivities;
20716            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20717                    "Item " + Integer.toHexString(System.identityHashCode(item))
20718                    + " " + app.toShortString() + ": changes=" + item.changes
20719                    + " procState=" + item.processState
20720                    + " foreground=" + item.foregroundActivities
20721                    + " type=" + app.adjType + " source=" + app.adjSource
20722                    + " target=" + app.adjTarget);
20723        }
20724
20725        return success;
20726    }
20727
20728    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20729        final UidRecord.ChangeItem pendingChange;
20730        if (uidRec == null || uidRec.pendingChange == null) {
20731            if (mPendingUidChanges.size() == 0) {
20732                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20733                        "*** Enqueueing dispatch uid changed!");
20734                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20735            }
20736            final int NA = mAvailUidChanges.size();
20737            if (NA > 0) {
20738                pendingChange = mAvailUidChanges.remove(NA-1);
20739                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20740                        "Retrieving available item: " + pendingChange);
20741            } else {
20742                pendingChange = new UidRecord.ChangeItem();
20743                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20744                        "Allocating new item: " + pendingChange);
20745            }
20746            if (uidRec != null) {
20747                uidRec.pendingChange = pendingChange;
20748                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20749                    // If this uid is going away, and we haven't yet reported it is gone,
20750                    // then do so now.
20751                    change = UidRecord.CHANGE_GONE_IDLE;
20752                }
20753            } else if (uid < 0) {
20754                throw new IllegalArgumentException("No UidRecord or uid");
20755            }
20756            pendingChange.uidRecord = uidRec;
20757            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20758            mPendingUidChanges.add(pendingChange);
20759        } else {
20760            pendingChange = uidRec.pendingChange;
20761            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20762                change = UidRecord.CHANGE_GONE_IDLE;
20763            }
20764        }
20765        pendingChange.change = change;
20766        pendingChange.processState = uidRec != null
20767                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20768    }
20769
20770    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20771            String authority) {
20772        if (app == null) return;
20773        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20774            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20775            if (userState == null) return;
20776            final long now = SystemClock.elapsedRealtime();
20777            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20778            if (lastReported == null || lastReported < now - 60 * 1000L) {
20779                if (mSystemReady) {
20780                    // Cannot touch the user stats if not system ready
20781                    mUsageStatsService.reportContentProviderUsage(
20782                            authority, providerPkgName, app.userId);
20783                }
20784                userState.mProviderLastReportedFg.put(authority, now);
20785            }
20786        }
20787    }
20788
20789    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20790        if (DEBUG_USAGE_STATS) {
20791            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20792                    + "] state changes: old = " + app.setProcState + ", new = "
20793                    + app.curProcState);
20794        }
20795        if (mUsageStatsService == null) {
20796            return;
20797        }
20798        boolean isInteraction;
20799        // To avoid some abuse patterns, we are going to be careful about what we consider
20800        // to be an app interaction.  Being the top activity doesn't count while the display
20801        // is sleeping, nor do short foreground services.
20802        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20803            isInteraction = true;
20804            app.fgInteractionTime = 0;
20805        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20806            if (app.fgInteractionTime == 0) {
20807                app.fgInteractionTime = nowElapsed;
20808                isInteraction = false;
20809            } else {
20810                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20811            }
20812        } else {
20813            // If the app was being forced to the foreground, by say a Toast, then
20814            // no need to treat it as an interaction
20815            isInteraction = app.forcingToForeground == null
20816                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20817            app.fgInteractionTime = 0;
20818        }
20819        if (isInteraction && (!app.reportedInteraction
20820                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20821            app.interactionEventTime = nowElapsed;
20822            String[] packages = app.getPackageList();
20823            if (packages != null) {
20824                for (int i = 0; i < packages.length; i++) {
20825                    mUsageStatsService.reportEvent(packages[i], app.userId,
20826                            UsageEvents.Event.SYSTEM_INTERACTION);
20827                }
20828            }
20829        }
20830        app.reportedInteraction = isInteraction;
20831        if (!isInteraction) {
20832            app.interactionEventTime = 0;
20833        }
20834    }
20835
20836    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20837        if (proc.thread != null) {
20838            if (proc.baseProcessTracker != null) {
20839                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20840            }
20841        }
20842    }
20843
20844    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20845            ProcessRecord TOP_APP, boolean doingAll, long now) {
20846        if (app.thread == null) {
20847            return false;
20848        }
20849
20850        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20851
20852        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20853    }
20854
20855    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20856            boolean oomAdj) {
20857        if (isForeground != proc.foregroundServices) {
20858            proc.foregroundServices = isForeground;
20859            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20860                    proc.info.uid);
20861            if (isForeground) {
20862                if (curProcs == null) {
20863                    curProcs = new ArrayList<ProcessRecord>();
20864                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20865                }
20866                if (!curProcs.contains(proc)) {
20867                    curProcs.add(proc);
20868                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20869                            proc.info.packageName, proc.info.uid);
20870                }
20871            } else {
20872                if (curProcs != null) {
20873                    if (curProcs.remove(proc)) {
20874                        mBatteryStatsService.noteEvent(
20875                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20876                                proc.info.packageName, proc.info.uid);
20877                        if (curProcs.size() <= 0) {
20878                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20879                        }
20880                    }
20881                }
20882            }
20883            if (oomAdj) {
20884                updateOomAdjLocked();
20885            }
20886        }
20887    }
20888
20889    private final ActivityRecord resumedAppLocked() {
20890        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20891        String pkg;
20892        int uid;
20893        if (act != null) {
20894            pkg = act.packageName;
20895            uid = act.info.applicationInfo.uid;
20896        } else {
20897            pkg = null;
20898            uid = -1;
20899        }
20900        // Has the UID or resumed package name changed?
20901        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20902                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20903            if (mCurResumedPackage != null) {
20904                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20905                        mCurResumedPackage, mCurResumedUid);
20906            }
20907            mCurResumedPackage = pkg;
20908            mCurResumedUid = uid;
20909            if (mCurResumedPackage != null) {
20910                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20911                        mCurResumedPackage, mCurResumedUid);
20912            }
20913        }
20914        return act;
20915    }
20916
20917    final boolean updateOomAdjLocked(ProcessRecord app) {
20918        final ActivityRecord TOP_ACT = resumedAppLocked();
20919        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20920        final boolean wasCached = app.cached;
20921
20922        mAdjSeq++;
20923
20924        // This is the desired cached adjusment we want to tell it to use.
20925        // If our app is currently cached, we know it, and that is it.  Otherwise,
20926        // we don't know it yet, and it needs to now be cached we will then
20927        // need to do a complete oom adj.
20928        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20929                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20930        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20931                SystemClock.uptimeMillis());
20932        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20933            // Changed to/from cached state, so apps after it in the LRU
20934            // list may also be changed.
20935            updateOomAdjLocked();
20936        }
20937        return success;
20938    }
20939
20940    final void updateOomAdjLocked() {
20941        final ActivityRecord TOP_ACT = resumedAppLocked();
20942        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20943        final long now = SystemClock.uptimeMillis();
20944        final long nowElapsed = SystemClock.elapsedRealtime();
20945        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20946        final int N = mLruProcesses.size();
20947
20948        if (false) {
20949            RuntimeException e = new RuntimeException();
20950            e.fillInStackTrace();
20951            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20952        }
20953
20954        // Reset state in all uid records.
20955        for (int i=mActiveUids.size()-1; i>=0; i--) {
20956            final UidRecord uidRec = mActiveUids.valueAt(i);
20957            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20958                    "Starting update of " + uidRec);
20959            uidRec.reset();
20960        }
20961
20962        mStackSupervisor.rankTaskLayersIfNeeded();
20963
20964        mAdjSeq++;
20965        mNewNumServiceProcs = 0;
20966        mNewNumAServiceProcs = 0;
20967
20968        final int emptyProcessLimit;
20969        final int cachedProcessLimit;
20970        if (mProcessLimit <= 0) {
20971            emptyProcessLimit = cachedProcessLimit = 0;
20972        } else if (mProcessLimit == 1) {
20973            emptyProcessLimit = 1;
20974            cachedProcessLimit = 0;
20975        } else {
20976            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20977            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20978        }
20979
20980        // Let's determine how many processes we have running vs.
20981        // how many slots we have for background processes; we may want
20982        // to put multiple processes in a slot of there are enough of
20983        // them.
20984        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20985                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20986        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20987        if (numEmptyProcs > cachedProcessLimit) {
20988            // If there are more empty processes than our limit on cached
20989            // processes, then use the cached process limit for the factor.
20990            // This ensures that the really old empty processes get pushed
20991            // down to the bottom, so if we are running low on memory we will
20992            // have a better chance at keeping around more cached processes
20993            // instead of a gazillion empty processes.
20994            numEmptyProcs = cachedProcessLimit;
20995        }
20996        int emptyFactor = numEmptyProcs/numSlots;
20997        if (emptyFactor < 1) emptyFactor = 1;
20998        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20999        if (cachedFactor < 1) cachedFactor = 1;
21000        int stepCached = 0;
21001        int stepEmpty = 0;
21002        int numCached = 0;
21003        int numEmpty = 0;
21004        int numTrimming = 0;
21005
21006        mNumNonCachedProcs = 0;
21007        mNumCachedHiddenProcs = 0;
21008
21009        // First update the OOM adjustment for each of the
21010        // application processes based on their current state.
21011        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21012        int nextCachedAdj = curCachedAdj+1;
21013        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21014        int nextEmptyAdj = curEmptyAdj+2;
21015        for (int i=N-1; i>=0; i--) {
21016            ProcessRecord app = mLruProcesses.get(i);
21017            if (!app.killedByAm && app.thread != null) {
21018                app.procStateChanged = false;
21019                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21020
21021                // If we haven't yet assigned the final cached adj
21022                // to the process, do that now.
21023                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21024                    switch (app.curProcState) {
21025                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21026                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21027                            // This process is a cached process holding activities...
21028                            // assign it the next cached value for that type, and then
21029                            // step that cached level.
21030                            app.curRawAdj = curCachedAdj;
21031                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21032                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21033                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21034                                    + ")");
21035                            if (curCachedAdj != nextCachedAdj) {
21036                                stepCached++;
21037                                if (stepCached >= cachedFactor) {
21038                                    stepCached = 0;
21039                                    curCachedAdj = nextCachedAdj;
21040                                    nextCachedAdj += 2;
21041                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21042                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21043                                    }
21044                                }
21045                            }
21046                            break;
21047                        default:
21048                            // For everything else, assign next empty cached process
21049                            // level and bump that up.  Note that this means that
21050                            // long-running services that have dropped down to the
21051                            // cached level will be treated as empty (since their process
21052                            // state is still as a service), which is what we want.
21053                            app.curRawAdj = curEmptyAdj;
21054                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21055                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21056                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21057                                    + ")");
21058                            if (curEmptyAdj != nextEmptyAdj) {
21059                                stepEmpty++;
21060                                if (stepEmpty >= emptyFactor) {
21061                                    stepEmpty = 0;
21062                                    curEmptyAdj = nextEmptyAdj;
21063                                    nextEmptyAdj += 2;
21064                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21065                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21066                                    }
21067                                }
21068                            }
21069                            break;
21070                    }
21071                }
21072
21073                applyOomAdjLocked(app, true, now, nowElapsed);
21074
21075                // Count the number of process types.
21076                switch (app.curProcState) {
21077                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21078                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21079                        mNumCachedHiddenProcs++;
21080                        numCached++;
21081                        if (numCached > cachedProcessLimit) {
21082                            app.kill("cached #" + numCached, true);
21083                        }
21084                        break;
21085                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21086                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21087                                && app.lastActivityTime < oldTime) {
21088                            app.kill("empty for "
21089                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21090                                    / 1000) + "s", true);
21091                        } else {
21092                            numEmpty++;
21093                            if (numEmpty > emptyProcessLimit) {
21094                                app.kill("empty #" + numEmpty, true);
21095                            }
21096                        }
21097                        break;
21098                    default:
21099                        mNumNonCachedProcs++;
21100                        break;
21101                }
21102
21103                if (app.isolated && app.services.size() <= 0) {
21104                    // If this is an isolated process, and there are no
21105                    // services running in it, then the process is no longer
21106                    // needed.  We agressively kill these because we can by
21107                    // definition not re-use the same process again, and it is
21108                    // good to avoid having whatever code was running in them
21109                    // left sitting around after no longer needed.
21110                    app.kill("isolated not needed", true);
21111                } else {
21112                    // Keeping this process, update its uid.
21113                    final UidRecord uidRec = app.uidRecord;
21114                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
21115                        uidRec.curProcState = app.curProcState;
21116                    }
21117                }
21118
21119                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21120                        && !app.killedByAm) {
21121                    numTrimming++;
21122                }
21123            }
21124        }
21125
21126        mNumServiceProcs = mNewNumServiceProcs;
21127
21128        // Now determine the memory trimming level of background processes.
21129        // Unfortunately we need to start at the back of the list to do this
21130        // properly.  We only do this if the number of background apps we
21131        // are managing to keep around is less than half the maximum we desire;
21132        // if we are keeping a good number around, we'll let them use whatever
21133        // memory they want.
21134        final int numCachedAndEmpty = numCached + numEmpty;
21135        int memFactor;
21136        if (numCached <= ProcessList.TRIM_CACHED_APPS
21137                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21138            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21139                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21140            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21141                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21142            } else {
21143                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21144            }
21145        } else {
21146            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21147        }
21148        // We always allow the memory level to go up (better).  We only allow it to go
21149        // down if we are in a state where that is allowed, *and* the total number of processes
21150        // has gone down since last time.
21151        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21152                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21153                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21154        if (memFactor > mLastMemoryLevel) {
21155            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21156                memFactor = mLastMemoryLevel;
21157                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21158            }
21159        }
21160        if (memFactor != mLastMemoryLevel) {
21161            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21162        }
21163        mLastMemoryLevel = memFactor;
21164        mLastNumProcesses = mLruProcesses.size();
21165        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21166        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21167        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21168            if (mLowRamStartTime == 0) {
21169                mLowRamStartTime = now;
21170            }
21171            int step = 0;
21172            int fgTrimLevel;
21173            switch (memFactor) {
21174                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21175                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21176                    break;
21177                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21178                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21179                    break;
21180                default:
21181                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21182                    break;
21183            }
21184            int factor = numTrimming/3;
21185            int minFactor = 2;
21186            if (mHomeProcess != null) minFactor++;
21187            if (mPreviousProcess != null) minFactor++;
21188            if (factor < minFactor) factor = minFactor;
21189            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21190            for (int i=N-1; i>=0; i--) {
21191                ProcessRecord app = mLruProcesses.get(i);
21192                if (allChanged || app.procStateChanged) {
21193                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21194                    app.procStateChanged = false;
21195                }
21196                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21197                        && !app.killedByAm) {
21198                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21199                        try {
21200                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21201                                    "Trimming memory of " + app.processName + " to " + curLevel);
21202                            app.thread.scheduleTrimMemory(curLevel);
21203                        } catch (RemoteException e) {
21204                        }
21205                        if (false) {
21206                            // For now we won't do this; our memory trimming seems
21207                            // to be good enough at this point that destroying
21208                            // activities causes more harm than good.
21209                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21210                                    && app != mHomeProcess && app != mPreviousProcess) {
21211                                // Need to do this on its own message because the stack may not
21212                                // be in a consistent state at this point.
21213                                // For these apps we will also finish their activities
21214                                // to help them free memory.
21215                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21216                            }
21217                        }
21218                    }
21219                    app.trimMemoryLevel = curLevel;
21220                    step++;
21221                    if (step >= factor) {
21222                        step = 0;
21223                        switch (curLevel) {
21224                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21225                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21226                                break;
21227                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21228                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21229                                break;
21230                        }
21231                    }
21232                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21233                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21234                            && app.thread != null) {
21235                        try {
21236                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21237                                    "Trimming memory of heavy-weight " + app.processName
21238                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21239                            app.thread.scheduleTrimMemory(
21240                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21241                        } catch (RemoteException e) {
21242                        }
21243                    }
21244                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21245                } else {
21246                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21247                            || app.systemNoUi) && app.pendingUiClean) {
21248                        // If this application is now in the background and it
21249                        // had done UI, then give it the special trim level to
21250                        // have it free UI resources.
21251                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21252                        if (app.trimMemoryLevel < level && app.thread != null) {
21253                            try {
21254                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21255                                        "Trimming memory of bg-ui " + app.processName
21256                                        + " to " + level);
21257                                app.thread.scheduleTrimMemory(level);
21258                            } catch (RemoteException e) {
21259                            }
21260                        }
21261                        app.pendingUiClean = false;
21262                    }
21263                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21264                        try {
21265                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21266                                    "Trimming memory of fg " + app.processName
21267                                    + " to " + fgTrimLevel);
21268                            app.thread.scheduleTrimMemory(fgTrimLevel);
21269                        } catch (RemoteException e) {
21270                        }
21271                    }
21272                    app.trimMemoryLevel = fgTrimLevel;
21273                }
21274            }
21275        } else {
21276            if (mLowRamStartTime != 0) {
21277                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21278                mLowRamStartTime = 0;
21279            }
21280            for (int i=N-1; i>=0; i--) {
21281                ProcessRecord app = mLruProcesses.get(i);
21282                if (allChanged || app.procStateChanged) {
21283                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21284                    app.procStateChanged = false;
21285                }
21286                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21287                        || app.systemNoUi) && app.pendingUiClean) {
21288                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21289                            && app.thread != null) {
21290                        try {
21291                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21292                                    "Trimming memory of ui hidden " + app.processName
21293                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21294                            app.thread.scheduleTrimMemory(
21295                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21296                        } catch (RemoteException e) {
21297                        }
21298                    }
21299                    app.pendingUiClean = false;
21300                }
21301                app.trimMemoryLevel = 0;
21302            }
21303        }
21304
21305        if (mAlwaysFinishActivities) {
21306            // Need to do this on its own message because the stack may not
21307            // be in a consistent state at this point.
21308            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21309        }
21310
21311        if (allChanged) {
21312            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21313        }
21314
21315        // Update from any uid changes.
21316        for (int i=mActiveUids.size()-1; i>=0; i--) {
21317            final UidRecord uidRec = mActiveUids.valueAt(i);
21318            int uidChange = UidRecord.CHANGE_PROCSTATE;
21319            if (uidRec.setProcState != uidRec.curProcState) {
21320                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21321                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21322                        + " to " + uidRec.curProcState);
21323                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21324                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21325                        uidRec.lastBackgroundTime = nowElapsed;
21326                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21327                            // Note: the background settle time is in elapsed realtime, while
21328                            // the handler time base is uptime.  All this means is that we may
21329                            // stop background uids later than we had intended, but that only
21330                            // happens because the device was sleeping so we are okay anyway.
21331                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21332                        }
21333                    }
21334                } else {
21335                    if (uidRec.idle) {
21336                        uidChange = UidRecord.CHANGE_ACTIVE;
21337                        uidRec.idle = false;
21338                    }
21339                    uidRec.lastBackgroundTime = 0;
21340                }
21341                uidRec.setProcState = uidRec.curProcState;
21342                enqueueUidChangeLocked(uidRec, -1, uidChange);
21343                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21344            }
21345        }
21346
21347        if (mProcessStats.shouldWriteNowLocked(now)) {
21348            mHandler.post(new Runnable() {
21349                @Override public void run() {
21350                    synchronized (ActivityManagerService.this) {
21351                        mProcessStats.writeStateAsyncLocked();
21352                    }
21353                }
21354            });
21355        }
21356
21357        if (DEBUG_OOM_ADJ) {
21358            final long duration = SystemClock.uptimeMillis() - now;
21359            if (false) {
21360                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21361                        new RuntimeException("here").fillInStackTrace());
21362            } else {
21363                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21364            }
21365        }
21366    }
21367
21368    final void idleUids() {
21369        synchronized (this) {
21370            final long nowElapsed = SystemClock.elapsedRealtime();
21371            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21372            long nextTime = 0;
21373            for (int i=mActiveUids.size()-1; i>=0; i--) {
21374                final UidRecord uidRec = mActiveUids.valueAt(i);
21375                final long bgTime = uidRec.lastBackgroundTime;
21376                if (bgTime > 0 && !uidRec.idle) {
21377                    if (bgTime <= maxBgTime) {
21378                        uidRec.idle = true;
21379                        doStopUidLocked(uidRec.uid, uidRec);
21380                    } else {
21381                        if (nextTime == 0 || nextTime > bgTime) {
21382                            nextTime = bgTime;
21383                        }
21384                    }
21385                }
21386            }
21387            if (nextTime > 0) {
21388                mHandler.removeMessages(IDLE_UIDS_MSG);
21389                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21390                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21391            }
21392        }
21393    }
21394
21395    final void runInBackgroundDisabled(int uid) {
21396        synchronized (this) {
21397            UidRecord uidRec = mActiveUids.get(uid);
21398            if (uidRec != null) {
21399                // This uid is actually running...  should it be considered background now?
21400                if (uidRec.idle) {
21401                    doStopUidLocked(uidRec.uid, uidRec);
21402                }
21403            } else {
21404                // This uid isn't actually running...  still send a report about it being "stopped".
21405                doStopUidLocked(uid, null);
21406            }
21407        }
21408    }
21409
21410    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21411        mServices.stopInBackgroundLocked(uid);
21412        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21413    }
21414
21415    final void trimApplications() {
21416        synchronized (this) {
21417            int i;
21418
21419            // First remove any unused application processes whose package
21420            // has been removed.
21421            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21422                final ProcessRecord app = mRemovedProcesses.get(i);
21423                if (app.activities.size() == 0
21424                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21425                    Slog.i(
21426                        TAG, "Exiting empty application process "
21427                        + app.toShortString() + " ("
21428                        + (app.thread != null ? app.thread.asBinder() : null)
21429                        + ")\n");
21430                    if (app.pid > 0 && app.pid != MY_PID) {
21431                        app.kill("empty", false);
21432                    } else {
21433                        try {
21434                            app.thread.scheduleExit();
21435                        } catch (Exception e) {
21436                            // Ignore exceptions.
21437                        }
21438                    }
21439                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21440                    mRemovedProcesses.remove(i);
21441
21442                    if (app.persistent) {
21443                        addAppLocked(app.info, false, null /* ABI override */);
21444                    }
21445                }
21446            }
21447
21448            // Now update the oom adj for all processes.
21449            updateOomAdjLocked();
21450        }
21451    }
21452
21453    /** This method sends the specified signal to each of the persistent apps */
21454    public void signalPersistentProcesses(int sig) throws RemoteException {
21455        if (sig != Process.SIGNAL_USR1) {
21456            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21457        }
21458
21459        synchronized (this) {
21460            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21461                    != PackageManager.PERMISSION_GRANTED) {
21462                throw new SecurityException("Requires permission "
21463                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21464            }
21465
21466            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21467                ProcessRecord r = mLruProcesses.get(i);
21468                if (r.thread != null && r.persistent) {
21469                    Process.sendSignal(r.pid, sig);
21470                }
21471            }
21472        }
21473    }
21474
21475    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21476        if (proc == null || proc == mProfileProc) {
21477            proc = mProfileProc;
21478            profileType = mProfileType;
21479            clearProfilerLocked();
21480        }
21481        if (proc == null) {
21482            return;
21483        }
21484        try {
21485            proc.thread.profilerControl(false, null, profileType);
21486        } catch (RemoteException e) {
21487            throw new IllegalStateException("Process disappeared");
21488        }
21489    }
21490
21491    private void clearProfilerLocked() {
21492        if (mProfileFd != null) {
21493            try {
21494                mProfileFd.close();
21495            } catch (IOException e) {
21496            }
21497        }
21498        mProfileApp = null;
21499        mProfileProc = null;
21500        mProfileFile = null;
21501        mProfileType = 0;
21502        mAutoStopProfiler = false;
21503        mSamplingInterval = 0;
21504    }
21505
21506    public boolean profileControl(String process, int userId, boolean start,
21507            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21508
21509        try {
21510            synchronized (this) {
21511                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21512                // its own permission.
21513                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21514                        != PackageManager.PERMISSION_GRANTED) {
21515                    throw new SecurityException("Requires permission "
21516                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21517                }
21518
21519                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21520                    throw new IllegalArgumentException("null profile info or fd");
21521                }
21522
21523                ProcessRecord proc = null;
21524                if (process != null) {
21525                    proc = findProcessLocked(process, userId, "profileControl");
21526                }
21527
21528                if (start && (proc == null || proc.thread == null)) {
21529                    throw new IllegalArgumentException("Unknown process: " + process);
21530                }
21531
21532                if (start) {
21533                    stopProfilerLocked(null, 0);
21534                    setProfileApp(proc.info, proc.processName, profilerInfo);
21535                    mProfileProc = proc;
21536                    mProfileType = profileType;
21537                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21538                    try {
21539                        fd = fd.dup();
21540                    } catch (IOException e) {
21541                        fd = null;
21542                    }
21543                    profilerInfo.profileFd = fd;
21544                    proc.thread.profilerControl(start, profilerInfo, profileType);
21545                    fd = null;
21546                    mProfileFd = null;
21547                } else {
21548                    stopProfilerLocked(proc, profileType);
21549                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21550                        try {
21551                            profilerInfo.profileFd.close();
21552                        } catch (IOException e) {
21553                        }
21554                    }
21555                }
21556
21557                return true;
21558            }
21559        } catch (RemoteException e) {
21560            throw new IllegalStateException("Process disappeared");
21561        } finally {
21562            if (profilerInfo != null && profilerInfo.profileFd != null) {
21563                try {
21564                    profilerInfo.profileFd.close();
21565                } catch (IOException e) {
21566                }
21567            }
21568        }
21569    }
21570
21571    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21572        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21573                userId, true, ALLOW_FULL_ONLY, callName, null);
21574        ProcessRecord proc = null;
21575        try {
21576            int pid = Integer.parseInt(process);
21577            synchronized (mPidsSelfLocked) {
21578                proc = mPidsSelfLocked.get(pid);
21579            }
21580        } catch (NumberFormatException e) {
21581        }
21582
21583        if (proc == null) {
21584            ArrayMap<String, SparseArray<ProcessRecord>> all
21585                    = mProcessNames.getMap();
21586            SparseArray<ProcessRecord> procs = all.get(process);
21587            if (procs != null && procs.size() > 0) {
21588                proc = procs.valueAt(0);
21589                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21590                    for (int i=1; i<procs.size(); i++) {
21591                        ProcessRecord thisProc = procs.valueAt(i);
21592                        if (thisProc.userId == userId) {
21593                            proc = thisProc;
21594                            break;
21595                        }
21596                    }
21597                }
21598            }
21599        }
21600
21601        return proc;
21602    }
21603
21604    public boolean dumpHeap(String process, int userId, boolean managed,
21605            String path, ParcelFileDescriptor fd) throws RemoteException {
21606
21607        try {
21608            synchronized (this) {
21609                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21610                // its own permission (same as profileControl).
21611                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21612                        != PackageManager.PERMISSION_GRANTED) {
21613                    throw new SecurityException("Requires permission "
21614                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21615                }
21616
21617                if (fd == null) {
21618                    throw new IllegalArgumentException("null fd");
21619                }
21620
21621                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21622                if (proc == null || proc.thread == null) {
21623                    throw new IllegalArgumentException("Unknown process: " + process);
21624                }
21625
21626                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21627                if (!isDebuggable) {
21628                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21629                        throw new SecurityException("Process not debuggable: " + proc);
21630                    }
21631                }
21632
21633                proc.thread.dumpHeap(managed, path, fd);
21634                fd = null;
21635                return true;
21636            }
21637        } catch (RemoteException e) {
21638            throw new IllegalStateException("Process disappeared");
21639        } finally {
21640            if (fd != null) {
21641                try {
21642                    fd.close();
21643                } catch (IOException e) {
21644                }
21645            }
21646        }
21647    }
21648
21649    @Override
21650    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21651            String reportPackage) {
21652        if (processName != null) {
21653            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21654                    "setDumpHeapDebugLimit()");
21655        } else {
21656            synchronized (mPidsSelfLocked) {
21657                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21658                if (proc == null) {
21659                    throw new SecurityException("No process found for calling pid "
21660                            + Binder.getCallingPid());
21661                }
21662                if (!Build.IS_DEBUGGABLE
21663                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21664                    throw new SecurityException("Not running a debuggable build");
21665                }
21666                processName = proc.processName;
21667                uid = proc.uid;
21668                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21669                    throw new SecurityException("Package " + reportPackage + " is not running in "
21670                            + proc);
21671                }
21672            }
21673        }
21674        synchronized (this) {
21675            if (maxMemSize > 0) {
21676                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21677            } else {
21678                if (uid != 0) {
21679                    mMemWatchProcesses.remove(processName, uid);
21680                } else {
21681                    mMemWatchProcesses.getMap().remove(processName);
21682                }
21683            }
21684        }
21685    }
21686
21687    @Override
21688    public void dumpHeapFinished(String path) {
21689        synchronized (this) {
21690            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21691                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21692                        + " does not match last pid " + mMemWatchDumpPid);
21693                return;
21694            }
21695            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21696                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21697                        + " does not match last path " + mMemWatchDumpFile);
21698                return;
21699            }
21700            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21701            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21702        }
21703    }
21704
21705    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21706    public void monitor() {
21707        synchronized (this) { }
21708    }
21709
21710    void onCoreSettingsChange(Bundle settings) {
21711        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21712            ProcessRecord processRecord = mLruProcesses.get(i);
21713            try {
21714                if (processRecord.thread != null) {
21715                    processRecord.thread.setCoreSettings(settings);
21716                }
21717            } catch (RemoteException re) {
21718                /* ignore */
21719            }
21720        }
21721    }
21722
21723    // Multi-user methods
21724
21725    /**
21726     * Start user, if its not already running, but don't bring it to foreground.
21727     */
21728    @Override
21729    public boolean startUserInBackground(final int userId) {
21730        return mUserController.startUser(userId, /* foreground */ false);
21731    }
21732
21733    @Override
21734    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21735        return mUserController.unlockUser(userId, token, secret, listener);
21736    }
21737
21738    @Override
21739    public boolean switchUser(final int targetUserId) {
21740        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21741        UserInfo currentUserInfo;
21742        UserInfo targetUserInfo;
21743        synchronized (this) {
21744            int currentUserId = mUserController.getCurrentUserIdLocked();
21745            currentUserInfo = mUserController.getUserInfo(currentUserId);
21746            targetUserInfo = mUserController.getUserInfo(targetUserId);
21747            if (targetUserInfo == null) {
21748                Slog.w(TAG, "No user info for user #" + targetUserId);
21749                return false;
21750            }
21751            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21752                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21753                        + " when device is in demo mode");
21754                return false;
21755            }
21756            if (!targetUserInfo.supportsSwitchTo()) {
21757                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21758                return false;
21759            }
21760            if (targetUserInfo.isManagedProfile()) {
21761                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21762                return false;
21763            }
21764            mUserController.setTargetUserIdLocked(targetUserId);
21765        }
21766        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21767        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21768        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21769        return true;
21770    }
21771
21772    void scheduleStartProfilesLocked() {
21773        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21774            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21775                    DateUtils.SECOND_IN_MILLIS);
21776        }
21777    }
21778
21779    @Override
21780    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21781        return mUserController.stopUser(userId, force, callback);
21782    }
21783
21784    @Override
21785    public UserInfo getCurrentUser() {
21786        return mUserController.getCurrentUser();
21787    }
21788
21789    @Override
21790    public boolean isUserRunning(int userId, int flags) {
21791        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21792                && checkCallingPermission(INTERACT_ACROSS_USERS)
21793                    != PackageManager.PERMISSION_GRANTED) {
21794            String msg = "Permission Denial: isUserRunning() from pid="
21795                    + Binder.getCallingPid()
21796                    + ", uid=" + Binder.getCallingUid()
21797                    + " requires " + INTERACT_ACROSS_USERS;
21798            Slog.w(TAG, msg);
21799            throw new SecurityException(msg);
21800        }
21801        synchronized (this) {
21802            return mUserController.isUserRunningLocked(userId, flags);
21803        }
21804    }
21805
21806    @Override
21807    public int[] getRunningUserIds() {
21808        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21809                != PackageManager.PERMISSION_GRANTED) {
21810            String msg = "Permission Denial: isUserRunning() from pid="
21811                    + Binder.getCallingPid()
21812                    + ", uid=" + Binder.getCallingUid()
21813                    + " requires " + INTERACT_ACROSS_USERS;
21814            Slog.w(TAG, msg);
21815            throw new SecurityException(msg);
21816        }
21817        synchronized (this) {
21818            return mUserController.getStartedUserArrayLocked();
21819        }
21820    }
21821
21822    @Override
21823    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21824        mUserController.registerUserSwitchObserver(observer, name);
21825    }
21826
21827    @Override
21828    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21829        mUserController.unregisterUserSwitchObserver(observer);
21830    }
21831
21832    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21833        if (info == null) return null;
21834        ApplicationInfo newInfo = new ApplicationInfo(info);
21835        newInfo.initForUser(userId);
21836        return newInfo;
21837    }
21838
21839    public boolean isUserStopped(int userId) {
21840        synchronized (this) {
21841            return mUserController.getStartedUserStateLocked(userId) == null;
21842        }
21843    }
21844
21845    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21846        if (aInfo == null
21847                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21848            return aInfo;
21849        }
21850
21851        ActivityInfo info = new ActivityInfo(aInfo);
21852        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21853        return info;
21854    }
21855
21856    private boolean processSanityChecksLocked(ProcessRecord process) {
21857        if (process == null || process.thread == null) {
21858            return false;
21859        }
21860
21861        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21862        if (!isDebuggable) {
21863            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21864                return false;
21865            }
21866        }
21867
21868        return true;
21869    }
21870
21871    public boolean startBinderTracking() throws RemoteException {
21872        synchronized (this) {
21873            mBinderTransactionTrackingEnabled = true;
21874            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21875            // permission (same as profileControl).
21876            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21877                    != PackageManager.PERMISSION_GRANTED) {
21878                throw new SecurityException("Requires permission "
21879                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21880            }
21881
21882            for (int i = 0; i < mLruProcesses.size(); i++) {
21883                ProcessRecord process = mLruProcesses.get(i);
21884                if (!processSanityChecksLocked(process)) {
21885                    continue;
21886                }
21887                try {
21888                    process.thread.startBinderTracking();
21889                } catch (RemoteException e) {
21890                    Log.v(TAG, "Process disappared");
21891                }
21892            }
21893            return true;
21894        }
21895    }
21896
21897    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21898        try {
21899            synchronized (this) {
21900                mBinderTransactionTrackingEnabled = false;
21901                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21902                // permission (same as profileControl).
21903                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21904                        != PackageManager.PERMISSION_GRANTED) {
21905                    throw new SecurityException("Requires permission "
21906                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21907                }
21908
21909                if (fd == null) {
21910                    throw new IllegalArgumentException("null fd");
21911                }
21912
21913                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21914                pw.println("Binder transaction traces for all processes.\n");
21915                for (ProcessRecord process : mLruProcesses) {
21916                    if (!processSanityChecksLocked(process)) {
21917                        continue;
21918                    }
21919
21920                    pw.println("Traces for process: " + process.processName);
21921                    pw.flush();
21922                    try {
21923                        TransferPipe tp = new TransferPipe();
21924                        try {
21925                            process.thread.stopBinderTrackingAndDump(
21926                                    tp.getWriteFd().getFileDescriptor());
21927                            tp.go(fd.getFileDescriptor());
21928                        } finally {
21929                            tp.kill();
21930                        }
21931                    } catch (IOException e) {
21932                        pw.println("Failure while dumping IPC traces from " + process +
21933                                ".  Exception: " + e);
21934                        pw.flush();
21935                    } catch (RemoteException e) {
21936                        pw.println("Got a RemoteException while dumping IPC traces from " +
21937                                process + ".  Exception: " + e);
21938                        pw.flush();
21939                    }
21940                }
21941                fd = null;
21942                return true;
21943            }
21944        } finally {
21945            if (fd != null) {
21946                try {
21947                    fd.close();
21948                } catch (IOException e) {
21949                }
21950            }
21951        }
21952    }
21953
21954    private final class LocalService extends ActivityManagerInternal {
21955        @Override
21956        public String checkContentProviderAccess(String authority, int userId) {
21957            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21958        }
21959
21960        @Override
21961        public void onWakefulnessChanged(int wakefulness) {
21962            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21963        }
21964
21965        @Override
21966        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21967                String processName, String abiOverride, int uid, Runnable crashHandler) {
21968            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21969                    processName, abiOverride, uid, crashHandler);
21970        }
21971
21972        @Override
21973        public SleepToken acquireSleepToken(String tag) {
21974            Preconditions.checkNotNull(tag);
21975
21976            synchronized (ActivityManagerService.this) {
21977                SleepTokenImpl token = new SleepTokenImpl(tag);
21978                mSleepTokens.add(token);
21979                updateSleepIfNeededLocked();
21980                return token;
21981            }
21982        }
21983
21984        @Override
21985        public ComponentName getHomeActivityForUser(int userId) {
21986            synchronized (ActivityManagerService.this) {
21987                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21988                return homeActivity == null ? null : homeActivity.realActivity;
21989            }
21990        }
21991
21992        @Override
21993        public void onUserRemoved(int userId) {
21994            synchronized (ActivityManagerService.this) {
21995                ActivityManagerService.this.onUserStoppedLocked(userId);
21996            }
21997        }
21998
21999        @Override
22000        public void onLocalVoiceInteractionStarted(IBinder activity,
22001                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22002            synchronized (ActivityManagerService.this) {
22003                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22004                        voiceSession, voiceInteractor);
22005            }
22006        }
22007
22008        @Override
22009        public void notifyStartingWindowDrawn() {
22010            synchronized (ActivityManagerService.this) {
22011                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22012            }
22013        }
22014
22015        @Override
22016        public void notifyAppTransitionStarting(int reason) {
22017            synchronized (ActivityManagerService.this) {
22018                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22019            }
22020        }
22021
22022        @Override
22023        public void notifyAppTransitionFinished() {
22024            synchronized (ActivityManagerService.this) {
22025                mStackSupervisor.notifyAppTransitionDone();
22026            }
22027        }
22028
22029        @Override
22030        public void notifyAppTransitionCancelled() {
22031            synchronized (ActivityManagerService.this) {
22032                mStackSupervisor.notifyAppTransitionDone();
22033            }
22034        }
22035
22036        @Override
22037        public List<IBinder> getTopVisibleActivities() {
22038            synchronized (ActivityManagerService.this) {
22039                return mStackSupervisor.getTopVisibleActivities();
22040            }
22041        }
22042
22043        @Override
22044        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22045            synchronized (ActivityManagerService.this) {
22046                mStackSupervisor.setDockedStackMinimized(minimized);
22047            }
22048        }
22049
22050        @Override
22051        public void killForegroundAppsForUser(int userHandle) {
22052            synchronized (ActivityManagerService.this) {
22053                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22054                final int NP = mProcessNames.getMap().size();
22055                for (int ip = 0; ip < NP; ip++) {
22056                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22057                    final int NA = apps.size();
22058                    for (int ia = 0; ia < NA; ia++) {
22059                        final ProcessRecord app = apps.valueAt(ia);
22060                        if (app.persistent) {
22061                            // We don't kill persistent processes.
22062                            continue;
22063                        }
22064                        if (app.removed) {
22065                            procs.add(app);
22066                        } else if (app.userId == userHandle && app.foregroundActivities) {
22067                            app.removed = true;
22068                            procs.add(app);
22069                        }
22070                    }
22071                }
22072
22073                final int N = procs.size();
22074                for (int i = 0; i < N; i++) {
22075                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22076                }
22077            }
22078        }
22079
22080        @Override
22081        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22082            if (!(target instanceof PendingIntentRecord)) {
22083                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22084                return;
22085            }
22086            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22087        }
22088
22089        @Override
22090        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22091                int userId) {
22092            Preconditions.checkNotNull(values, "Configuration must not be null");
22093            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22094            synchronized (ActivityManagerService.this) {
22095                updateConfigurationLocked(values, null, false, true, userId,
22096                        false /* deferResume */);
22097            }
22098        }
22099
22100        @Override
22101        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22102                Bundle bOptions) {
22103            Preconditions.checkNotNull(intents, "intents");
22104            final String[] resolvedTypes = new String[intents.length];
22105            for (int i = 0; i < intents.length; i++) {
22106                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22107            }
22108
22109            // UID of the package on user userId.
22110            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22111            // packageUid may not be initialized.
22112            int packageUid = 0;
22113            try {
22114                packageUid = AppGlobals.getPackageManager().getPackageUid(
22115                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22116            } catch (RemoteException e) {
22117                // Shouldn't happen.
22118            }
22119
22120            synchronized (ActivityManagerService.this) {
22121                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22122                        /*resultTo*/ null, bOptions, userId);
22123            }
22124        }
22125
22126        @Override
22127        public int getUidProcessState(int uid) {
22128            return getUidState(uid);
22129        }
22130    }
22131
22132    private final class SleepTokenImpl extends SleepToken {
22133        private final String mTag;
22134        private final long mAcquireTime;
22135
22136        public SleepTokenImpl(String tag) {
22137            mTag = tag;
22138            mAcquireTime = SystemClock.uptimeMillis();
22139        }
22140
22141        @Override
22142        public void release() {
22143            synchronized (ActivityManagerService.this) {
22144                if (mSleepTokens.remove(this)) {
22145                    updateSleepIfNeededLocked();
22146                }
22147            }
22148        }
22149
22150        @Override
22151        public String toString() {
22152            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22153        }
22154    }
22155
22156    /**
22157     * An implementation of IAppTask, that allows an app to manage its own tasks via
22158     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22159     * only the process that calls getAppTasks() can call the AppTask methods.
22160     */
22161    class AppTaskImpl extends IAppTask.Stub {
22162        private int mTaskId;
22163        private int mCallingUid;
22164
22165        public AppTaskImpl(int taskId, int callingUid) {
22166            mTaskId = taskId;
22167            mCallingUid = callingUid;
22168        }
22169
22170        private void checkCaller() {
22171            if (mCallingUid != Binder.getCallingUid()) {
22172                throw new SecurityException("Caller " + mCallingUid
22173                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22174            }
22175        }
22176
22177        @Override
22178        public void finishAndRemoveTask() {
22179            checkCaller();
22180
22181            synchronized (ActivityManagerService.this) {
22182                long origId = Binder.clearCallingIdentity();
22183                try {
22184                    // We remove the task from recents to preserve backwards
22185                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22186                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22187                    }
22188                } finally {
22189                    Binder.restoreCallingIdentity(origId);
22190                }
22191            }
22192        }
22193
22194        @Override
22195        public ActivityManager.RecentTaskInfo getTaskInfo() {
22196            checkCaller();
22197
22198            synchronized (ActivityManagerService.this) {
22199                long origId = Binder.clearCallingIdentity();
22200                try {
22201                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22202                    if (tr == null) {
22203                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22204                    }
22205                    return createRecentTaskInfoFromTaskRecord(tr);
22206                } finally {
22207                    Binder.restoreCallingIdentity(origId);
22208                }
22209            }
22210        }
22211
22212        @Override
22213        public void moveToFront() {
22214            checkCaller();
22215            // Will bring task to front if it already has a root activity.
22216            final long origId = Binder.clearCallingIdentity();
22217            try {
22218                synchronized (this) {
22219                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22220                }
22221            } finally {
22222                Binder.restoreCallingIdentity(origId);
22223            }
22224        }
22225
22226        @Override
22227        public int startActivity(IBinder whoThread, String callingPackage,
22228                Intent intent, String resolvedType, Bundle bOptions) {
22229            checkCaller();
22230
22231            int callingUser = UserHandle.getCallingUserId();
22232            TaskRecord tr;
22233            IApplicationThread appThread;
22234            synchronized (ActivityManagerService.this) {
22235                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22236                if (tr == null) {
22237                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22238                }
22239                appThread = ApplicationThreadNative.asInterface(whoThread);
22240                if (appThread == null) {
22241                    throw new IllegalArgumentException("Bad app thread " + appThread);
22242                }
22243            }
22244            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22245                    resolvedType, null, null, null, null, 0, 0, null, null,
22246                    null, bOptions, false, callingUser, null, tr);
22247        }
22248
22249        @Override
22250        public void setExcludeFromRecents(boolean exclude) {
22251            checkCaller();
22252
22253            synchronized (ActivityManagerService.this) {
22254                long origId = Binder.clearCallingIdentity();
22255                try {
22256                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22257                    if (tr == null) {
22258                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22259                    }
22260                    Intent intent = tr.getBaseIntent();
22261                    if (exclude) {
22262                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22263                    } else {
22264                        intent.setFlags(intent.getFlags()
22265                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22266                    }
22267                } finally {
22268                    Binder.restoreCallingIdentity(origId);
22269                }
22270            }
22271        }
22272    }
22273
22274    /**
22275     * Kill processes for the user with id userId and that depend on the package named packageName
22276     */
22277    @Override
22278    public void killPackageDependents(String packageName, int userId) {
22279        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22280        if (packageName == null) {
22281            throw new NullPointerException(
22282                    "Cannot kill the dependents of a package without its name.");
22283        }
22284
22285        long callingId = Binder.clearCallingIdentity();
22286        IPackageManager pm = AppGlobals.getPackageManager();
22287        int pkgUid = -1;
22288        try {
22289            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22290        } catch (RemoteException e) {
22291        }
22292        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22293            throw new IllegalArgumentException(
22294                    "Cannot kill dependents of non-existing package " + packageName);
22295        }
22296        try {
22297            synchronized(this) {
22298                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22299                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22300                        "dep: " + packageName);
22301            }
22302        } finally {
22303            Binder.restoreCallingIdentity(callingId);
22304        }
22305    }
22306
22307    @Override
22308    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22309        final int userId = intent.getCreatorUserHandle().getIdentifier();
22310        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22311            return false;
22312        }
22313        IIntentSender target = intent.getTarget();
22314        if (!(target instanceof PendingIntentRecord)) {
22315            return false;
22316        }
22317        final PendingIntentRecord record = (PendingIntentRecord) target;
22318        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22319                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22320        // For direct boot aware activities, they can be shown without triggering a work challenge
22321        // before the profile user is unlocked.
22322        return rInfo != null && rInfo.activityInfo != null;
22323    }
22324}
22325