ActivityManagerService.java revision 33eb07f5759b85a5617f8057d8a335019c7d24dd
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.NonNull;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
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.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    // Whether we should use SCHED_FIFO for UI and RenderThreads.
573    private boolean mUseFifoUiScheduling = false;
574
575    BroadcastQueue mFgBroadcastQueue;
576    BroadcastQueue mBgBroadcastQueue;
577    // Convenient for easy iteration over the queues. Foreground is first
578    // so that dispatch of foreground broadcasts gets precedence.
579    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580
581    BroadcastStats mLastBroadcastStats;
582    BroadcastStats mCurBroadcastStats;
583
584    BroadcastQueue broadcastQueueForIntent(Intent intent) {
585        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                "Broadcast intent " + intent + " on "
588                + (isFg ? "foreground" : "background") + " queue");
589        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590    }
591
592    /**
593     * Activity we have told the window manager to have key focus.
594     */
595    ActivityRecord mFocusedActivity = null;
596
597    /**
598     * User id of the last activity mFocusedActivity was set to.
599     */
600    private int mLastFocusedUserId;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    boolean mDoingSetFocusedActivity;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown;
645    }
646
647    // it's a semaphore; boost when 0->1, reset when 1->0
648    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
649        @Override protected Integer initialValue() {
650            return 0;
651        }
652    };
653
654    static void boostPriorityForLockedSection() {
655        if (sIsBoosted.get() == 0) {
656            // boost to prio 118 while holding a global lock
657            Process.setThreadPriority(Process.myTid(), -2);
658            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
659        }
660        int cur = sIsBoosted.get();
661        sIsBoosted.set(cur + 1);
662    }
663
664    static void resetPriorityAfterLockedSection() {
665        sIsBoosted.set(sIsBoosted.get() - 1);
666        if (sIsBoosted.get() == 0) {
667            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
668            Process.setThreadPriority(Process.myTid(), 0);
669        }
670    }
671    public class PendingAssistExtras extends Binder implements Runnable {
672        public final ActivityRecord activity;
673        public final Bundle extras;
674        public final Intent intent;
675        public final String hint;
676        public final IResultReceiver receiver;
677        public final int userHandle;
678        public boolean haveResult = false;
679        public Bundle result = null;
680        public AssistStructure structure = null;
681        public AssistContent content = null;
682        public Bundle receiverExtras;
683
684        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
685                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
686            activity = _activity;
687            extras = _extras;
688            intent = _intent;
689            hint = _hint;
690            receiver = _receiver;
691            receiverExtras = _receiverExtras;
692            userHandle = _userHandle;
693        }
694        @Override
695        public void run() {
696            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
697            synchronized (this) {
698                haveResult = true;
699                notifyAll();
700            }
701            pendingAssistExtrasTimedOut(this);
702        }
703    }
704
705    final ArrayList<PendingAssistExtras> mPendingAssistExtras
706            = new ArrayList<PendingAssistExtras>();
707
708    /**
709     * Process management.
710     */
711    final ProcessList mProcessList = new ProcessList();
712
713    /**
714     * All of the applications we currently have running organized by name.
715     * The keys are strings of the application package name (as
716     * returned by the package manager), and the keys are ApplicationRecord
717     * objects.
718     */
719    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
720
721    /**
722     * Tracking long-term execution of processes to look for abuse and other
723     * bad app behavior.
724     */
725    final ProcessStatsService mProcessStats;
726
727    /**
728     * The currently running isolated processes.
729     */
730    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
731
732    /**
733     * Counter for assigning isolated process uids, to avoid frequently reusing the
734     * same ones.
735     */
736    int mNextIsolatedProcessUid = 0;
737
738    /**
739     * The currently running heavy-weight process, if any.
740     */
741    ProcessRecord mHeavyWeightProcess = null;
742
743    /**
744     * All of the processes we currently have running organized by pid.
745     * The keys are the pid running the application.
746     *
747     * <p>NOTE: This object is protected by its own lock, NOT the global
748     * activity manager lock!
749     */
750    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
751
752    /**
753     * All of the processes that have been forced to be foreground.  The key
754     * is the pid of the caller who requested it (we hold a death
755     * link on it).
756     */
757    abstract class ForegroundToken implements IBinder.DeathRecipient {
758        int pid;
759        IBinder token;
760    }
761    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
762
763    /**
764     * List of records for processes that someone had tried to start before the
765     * system was ready.  We don't start them at that point, but ensure they
766     * are started by the time booting is complete.
767     */
768    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of persistent applications that are in the process
772     * of being started.
773     */
774    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Processes that are being forcibly torn down.
778     */
779    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
780
781    /**
782     * List of running applications, sorted by recent usage.
783     * The first entry in the list is the least recently used.
784     */
785    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
786
787    /**
788     * Where in mLruProcesses that the processes hosting activities start.
789     */
790    int mLruProcessActivityStart = 0;
791
792    /**
793     * Where in mLruProcesses that the processes hosting services start.
794     * This is after (lower index) than mLruProcessesActivityStart.
795     */
796    int mLruProcessServiceStart = 0;
797
798    /**
799     * List of processes that should gc as soon as things are idle.
800     */
801    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
802
803    /**
804     * Processes we want to collect PSS data from.
805     */
806    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
807
808    private boolean mBinderTransactionTrackingEnabled = false;
809
810    /**
811     * Last time we requested PSS data of all processes.
812     */
813    long mLastFullPssTime = SystemClock.uptimeMillis();
814
815    /**
816     * If set, the next time we collect PSS data we should do a full collection
817     * with data from native processes and the kernel.
818     */
819    boolean mFullPssPending = false;
820
821    /**
822     * This is the process holding what we currently consider to be
823     * the "home" activity.
824     */
825    ProcessRecord mHomeProcess;
826
827    /**
828     * This is the process holding the activity the user last visited that
829     * is in a different process from the one they are currently in.
830     */
831    ProcessRecord mPreviousProcess;
832
833    /**
834     * The time at which the previous process was last visible.
835     */
836    long mPreviousProcessVisibleTime;
837
838    /**
839     * Track all uids that have actively running processes.
840     */
841    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
842
843    /**
844     * This is for verifying the UID report flow.
845     */
846    static final boolean VALIDATE_UID_STATES = true;
847    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
848
849    /**
850     * Packages that the user has asked to have run in screen size
851     * compatibility mode instead of filling the screen.
852     */
853    final CompatModePackages mCompatModePackages;
854
855    /**
856     * Set of IntentSenderRecord objects that are currently active.
857     */
858    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
859            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
860
861    /**
862     * Fingerprints (hashCode()) of stack traces that we've
863     * already logged DropBox entries for.  Guarded by itself.  If
864     * something (rogue user app) forces this over
865     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
866     */
867    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
868    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
869
870    /**
871     * Strict Mode background batched logging state.
872     *
873     * The string buffer is guarded by itself, and its lock is also
874     * used to determine if another batched write is already
875     * in-flight.
876     */
877    private final StringBuilder mStrictModeBuffer = new StringBuilder();
878
879    /**
880     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
881     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
882     */
883    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
884
885    /**
886     * Resolver for broadcast intents to registered receivers.
887     * Holds BroadcastFilter (subclass of IntentFilter).
888     */
889    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
890            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
891        @Override
892        protected boolean allowFilterResult(
893                BroadcastFilter filter, List<BroadcastFilter> dest) {
894            IBinder target = filter.receiverList.receiver.asBinder();
895            for (int i = dest.size() - 1; i >= 0; i--) {
896                if (dest.get(i).receiverList.receiver.asBinder() == target) {
897                    return false;
898                }
899            }
900            return true;
901        }
902
903        @Override
904        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
905            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
906                    || userId == filter.owningUserId) {
907                return super.newResult(filter, match, userId);
908            }
909            return null;
910        }
911
912        @Override
913        protected BroadcastFilter[] newArray(int size) {
914            return new BroadcastFilter[size];
915        }
916
917        @Override
918        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
919            return packageName.equals(filter.packageName);
920        }
921    };
922
923    /**
924     * State of all active sticky broadcasts per user.  Keys are the action of the
925     * sticky Intent, values are an ArrayList of all broadcasted intents with
926     * that action (which should usually be one).  The SparseArray is keyed
927     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
928     * for stickies that are sent to all users.
929     */
930    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
931            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
932
933    final ActiveServices mServices;
934
935    final static class Association {
936        final int mSourceUid;
937        final String mSourceProcess;
938        final int mTargetUid;
939        final ComponentName mTargetComponent;
940        final String mTargetProcess;
941
942        int mCount;
943        long mTime;
944
945        int mNesting;
946        long mStartTime;
947
948        // states of the source process when the bind occurred.
949        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
950        long mLastStateUptime;
951        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
952                - ActivityManager.MIN_PROCESS_STATE+1];
953
954        Association(int sourceUid, String sourceProcess, int targetUid,
955                ComponentName targetComponent, String targetProcess) {
956            mSourceUid = sourceUid;
957            mSourceProcess = sourceProcess;
958            mTargetUid = targetUid;
959            mTargetComponent = targetComponent;
960            mTargetProcess = targetProcess;
961        }
962    }
963
964    /**
965     * When service association tracking is enabled, this is all of the associations we
966     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
967     * -> association data.
968     */
969    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
970            mAssociations = new SparseArray<>();
971    boolean mTrackingAssociations;
972
973    /**
974     * Backup/restore process management
975     */
976    String mBackupAppName = null;
977    BackupRecord mBackupTarget = null;
978
979    final ProviderMap mProviderMap;
980
981    /**
982     * List of content providers who have clients waiting for them.  The
983     * application is currently being launched and the provider will be
984     * removed from this list once it is published.
985     */
986    final ArrayList<ContentProviderRecord> mLaunchingProviders
987            = new ArrayList<ContentProviderRecord>();
988
989    /**
990     * File storing persisted {@link #mGrantedUriPermissions}.
991     */
992    private final AtomicFile mGrantFile;
993
994    /** XML constants used in {@link #mGrantFile} */
995    private static final String TAG_URI_GRANTS = "uri-grants";
996    private static final String TAG_URI_GRANT = "uri-grant";
997    private static final String ATTR_USER_HANDLE = "userHandle";
998    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
999    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1000    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1001    private static final String ATTR_TARGET_PKG = "targetPkg";
1002    private static final String ATTR_URI = "uri";
1003    private static final String ATTR_MODE_FLAGS = "modeFlags";
1004    private static final String ATTR_CREATED_TIME = "createdTime";
1005    private static final String ATTR_PREFIX = "prefix";
1006
1007    /**
1008     * Global set of specific {@link Uri} permissions that have been granted.
1009     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1010     * to {@link UriPermission#uri} to {@link UriPermission}.
1011     */
1012    @GuardedBy("this")
1013    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1014            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1015
1016    public static class GrantUri {
1017        public final int sourceUserId;
1018        public final Uri uri;
1019        public boolean prefix;
1020
1021        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1022            this.sourceUserId = sourceUserId;
1023            this.uri = uri;
1024            this.prefix = prefix;
1025        }
1026
1027        @Override
1028        public int hashCode() {
1029            int hashCode = 1;
1030            hashCode = 31 * hashCode + sourceUserId;
1031            hashCode = 31 * hashCode + uri.hashCode();
1032            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1033            return hashCode;
1034        }
1035
1036        @Override
1037        public boolean equals(Object o) {
1038            if (o instanceof GrantUri) {
1039                GrantUri other = (GrantUri) o;
1040                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1041                        && prefix == other.prefix;
1042            }
1043            return false;
1044        }
1045
1046        @Override
1047        public String toString() {
1048            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1049            if (prefix) result += " [prefix]";
1050            return result;
1051        }
1052
1053        public String toSafeString() {
1054            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1055            if (prefix) result += " [prefix]";
1056            return result;
1057        }
1058
1059        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1060            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1061                    ContentProvider.getUriWithoutUserId(uri), false);
1062        }
1063    }
1064
1065    CoreSettingsObserver mCoreSettingsObserver;
1066
1067    FontScaleSettingObserver mFontScaleSettingObserver;
1068
1069    private final class FontScaleSettingObserver extends ContentObserver {
1070        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1071
1072        public FontScaleSettingObserver() {
1073            super(mHandler);
1074            ContentResolver resolver = mContext.getContentResolver();
1075            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1076        }
1077
1078        @Override
1079        public void onChange(boolean selfChange, Uri uri) {
1080            if (mFontScaleUri.equals(uri)) {
1081                updateFontScaleIfNeeded();
1082            }
1083        }
1084    }
1085
1086    /**
1087     * Thread-local storage used to carry caller permissions over through
1088     * indirect content-provider access.
1089     */
1090    private class Identity {
1091        public final IBinder token;
1092        public final int pid;
1093        public final int uid;
1094
1095        Identity(IBinder _token, int _pid, int _uid) {
1096            token = _token;
1097            pid = _pid;
1098            uid = _uid;
1099        }
1100    }
1101
1102    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1103
1104    /**
1105     * All information we have collected about the runtime performance of
1106     * any user id that can impact battery performance.
1107     */
1108    final BatteryStatsService mBatteryStatsService;
1109
1110    /**
1111     * Information about component usage
1112     */
1113    UsageStatsManagerInternal mUsageStatsService;
1114
1115    /**
1116     * Access to DeviceIdleController service.
1117     */
1118    DeviceIdleController.LocalService mLocalDeviceIdleController;
1119
1120    /**
1121     * Information about and control over application operations
1122     */
1123    final AppOpsService mAppOpsService;
1124
1125    /**
1126     * Current configuration information.  HistoryRecord objects are given
1127     * a reference to this object to indicate which configuration they are
1128     * currently running in, so this object must be kept immutable.
1129     */
1130    Configuration mConfiguration = new Configuration();
1131
1132    /**
1133     * Current sequencing integer of the configuration, for skipping old
1134     * configurations.
1135     */
1136    int mConfigurationSeq = 0;
1137
1138    boolean mSuppressResizeConfigChanges = false;
1139
1140    /**
1141     * Hardware-reported OpenGLES version.
1142     */
1143    final int GL_ES_VERSION;
1144
1145    /**
1146     * List of initialization arguments to pass to all processes when binding applications to them.
1147     * For example, references to the commonly used services.
1148     */
1149    HashMap<String, IBinder> mAppBindArgs;
1150
1151    /**
1152     * Temporary to avoid allocations.  Protected by main lock.
1153     */
1154    final StringBuilder mStringBuilder = new StringBuilder(256);
1155
1156    /**
1157     * Used to control how we initialize the service.
1158     */
1159    ComponentName mTopComponent;
1160    String mTopAction = Intent.ACTION_MAIN;
1161    String mTopData;
1162
1163    volatile boolean mProcessesReady = false;
1164    volatile boolean mSystemReady = false;
1165    volatile boolean mOnBattery = false;
1166    volatile int mFactoryTest;
1167
1168    @GuardedBy("this") boolean mBooting = false;
1169    @GuardedBy("this") boolean mCallFinishBooting = false;
1170    @GuardedBy("this") boolean mBootAnimationComplete = false;
1171    @GuardedBy("this") boolean mLaunchWarningShown = false;
1172    @GuardedBy("this") boolean mCheckedForSetup = false;
1173
1174    Context mContext;
1175
1176    /**
1177     * The time at which we will allow normal application switches again,
1178     * after a call to {@link #stopAppSwitches()}.
1179     */
1180    long mAppSwitchesAllowedTime;
1181
1182    /**
1183     * This is set to true after the first switch after mAppSwitchesAllowedTime
1184     * is set; any switches after that will clear the time.
1185     */
1186    boolean mDidAppSwitch;
1187
1188    /**
1189     * Last time (in realtime) at which we checked for power usage.
1190     */
1191    long mLastPowerCheckRealtime;
1192
1193    /**
1194     * Last time (in uptime) at which we checked for power usage.
1195     */
1196    long mLastPowerCheckUptime;
1197
1198    /**
1199     * Set while we are wanting to sleep, to prevent any
1200     * activities from being started/resumed.
1201     */
1202    private boolean mSleeping = false;
1203
1204    /**
1205     * The process state used for processes that are running the top activities.
1206     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1207     */
1208    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1209
1210    /**
1211     * Set while we are running a voice interaction.  This overrides
1212     * sleeping while it is active.
1213     */
1214    private IVoiceInteractionSession mRunningVoice;
1215
1216    /**
1217     * For some direct access we need to power manager.
1218     */
1219    PowerManagerInternal mLocalPowerManager;
1220
1221    /**
1222     * We want to hold a wake lock while running a voice interaction session, since
1223     * this may happen with the screen off and we need to keep the CPU running to
1224     * be able to continue to interact with the user.
1225     */
1226    PowerManager.WakeLock mVoiceWakeLock;
1227
1228    /**
1229     * State of external calls telling us if the device is awake or asleep.
1230     */
1231    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1232
1233    /**
1234     * A list of tokens that cause the top activity to be put to sleep.
1235     * They are used by components that may hide and block interaction with underlying
1236     * activities.
1237     */
1238    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1239
1240    static final int LOCK_SCREEN_HIDDEN = 0;
1241    static final int LOCK_SCREEN_LEAVING = 1;
1242    static final int LOCK_SCREEN_SHOWN = 2;
1243    /**
1244     * State of external call telling us if the lock screen is shown.
1245     */
1246    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1247
1248    /**
1249     * Set if we are shutting down the system, similar to sleeping.
1250     */
1251    boolean mShuttingDown = false;
1252
1253    /**
1254     * Current sequence id for oom_adj computation traversal.
1255     */
1256    int mAdjSeq = 0;
1257
1258    /**
1259     * Current sequence id for process LRU updating.
1260     */
1261    int mLruSeq = 0;
1262
1263    /**
1264     * Keep track of the non-cached/empty process we last found, to help
1265     * determine how to distribute cached/empty processes next time.
1266     */
1267    int mNumNonCachedProcs = 0;
1268
1269    /**
1270     * Keep track of the number of cached hidden procs, to balance oom adj
1271     * distribution between those and empty procs.
1272     */
1273    int mNumCachedHiddenProcs = 0;
1274
1275    /**
1276     * Keep track of the number of service processes we last found, to
1277     * determine on the next iteration which should be B services.
1278     */
1279    int mNumServiceProcs = 0;
1280    int mNewNumAServiceProcs = 0;
1281    int mNewNumServiceProcs = 0;
1282
1283    /**
1284     * Allow the current computed overall memory level of the system to go down?
1285     * This is set to false when we are killing processes for reasons other than
1286     * memory management, so that the now smaller process list will not be taken as
1287     * an indication that memory is tighter.
1288     */
1289    boolean mAllowLowerMemLevel = false;
1290
1291    /**
1292     * The last computed memory level, for holding when we are in a state that
1293     * processes are going away for other reasons.
1294     */
1295    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1296
1297    /**
1298     * The last total number of process we have, to determine if changes actually look
1299     * like a shrinking number of process due to lower RAM.
1300     */
1301    int mLastNumProcesses;
1302
1303    /**
1304     * The uptime of the last time we performed idle maintenance.
1305     */
1306    long mLastIdleTime = SystemClock.uptimeMillis();
1307
1308    /**
1309     * Total time spent with RAM that has been added in the past since the last idle time.
1310     */
1311    long mLowRamTimeSinceLastIdle = 0;
1312
1313    /**
1314     * If RAM is currently low, when that horrible situation started.
1315     */
1316    long mLowRamStartTime = 0;
1317
1318    /**
1319     * For reporting to battery stats the current top application.
1320     */
1321    private String mCurResumedPackage = null;
1322    private int mCurResumedUid = -1;
1323
1324    /**
1325     * For reporting to battery stats the apps currently running foreground
1326     * service.  The ProcessMap is package/uid tuples; each of these contain
1327     * an array of the currently foreground processes.
1328     */
1329    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1330            = new ProcessMap<ArrayList<ProcessRecord>>();
1331
1332    /**
1333     * This is set if we had to do a delayed dexopt of an app before launching
1334     * it, to increase the ANR timeouts in that case.
1335     */
1336    boolean mDidDexOpt;
1337
1338    /**
1339     * Set if the systemServer made a call to enterSafeMode.
1340     */
1341    boolean mSafeMode;
1342
1343    /**
1344     * If true, we are running under a test environment so will sample PSS from processes
1345     * much more rapidly to try to collect better data when the tests are rapidly
1346     * running through apps.
1347     */
1348    boolean mTestPssMode = false;
1349
1350    String mDebugApp = null;
1351    boolean mWaitForDebugger = false;
1352    boolean mDebugTransient = false;
1353    String mOrigDebugApp = null;
1354    boolean mOrigWaitForDebugger = false;
1355    boolean mAlwaysFinishActivities = false;
1356    boolean mLenientBackgroundCheck = false;
1357    boolean mForceResizableActivities;
1358    boolean mSupportsMultiWindow;
1359    boolean mSupportsFreeformWindowManagement;
1360    boolean mSupportsPictureInPicture;
1361    boolean mSupportsLeanbackOnly;
1362    Rect mDefaultPinnedStackBounds;
1363    IActivityController mController = null;
1364    boolean mControllerIsAMonkey = false;
1365    String mProfileApp = null;
1366    ProcessRecord mProfileProc = null;
1367    String mProfileFile;
1368    ParcelFileDescriptor mProfileFd;
1369    int mSamplingInterval = 0;
1370    boolean mAutoStopProfiler = false;
1371    int mProfileType = 0;
1372    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1373    String mMemWatchDumpProcName;
1374    String mMemWatchDumpFile;
1375    int mMemWatchDumpPid;
1376    int mMemWatchDumpUid;
1377    String mTrackAllocationApp = null;
1378    String mNativeDebuggingApp = null;
1379
1380    final long[] mTmpLong = new long[2];
1381
1382    static final class ProcessChangeItem {
1383        static final int CHANGE_ACTIVITIES = 1<<0;
1384        static final int CHANGE_PROCESS_STATE = 1<<1;
1385        int changes;
1386        int uid;
1387        int pid;
1388        int processState;
1389        boolean foregroundActivities;
1390    }
1391
1392    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1393    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1394
1395    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1396    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1397
1398    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1399    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1400
1401    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1402    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1403
1404    /**
1405     * Runtime CPU use collection thread.  This object's lock is used to
1406     * perform synchronization with the thread (notifying it to run).
1407     */
1408    final Thread mProcessCpuThread;
1409
1410    /**
1411     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1412     * Must acquire this object's lock when accessing it.
1413     * NOTE: this lock will be held while doing long operations (trawling
1414     * through all processes in /proc), so it should never be acquired by
1415     * any critical paths such as when holding the main activity manager lock.
1416     */
1417    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1418            MONITOR_THREAD_CPU_USAGE);
1419    final AtomicLong mLastCpuTime = new AtomicLong(0);
1420    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1421
1422    long mLastWriteTime = 0;
1423
1424    /**
1425     * Used to retain an update lock when the foreground activity is in
1426     * immersive mode.
1427     */
1428    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1429
1430    /**
1431     * Set to true after the system has finished booting.
1432     */
1433    boolean mBooted = false;
1434
1435    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1436    int mProcessLimitOverride = -1;
1437
1438    WindowManagerService mWindowManager;
1439    final ActivityThread mSystemThread;
1440
1441    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1442        final ProcessRecord mApp;
1443        final int mPid;
1444        final IApplicationThread mAppThread;
1445
1446        AppDeathRecipient(ProcessRecord app, int pid,
1447                IApplicationThread thread) {
1448            if (DEBUG_ALL) Slog.v(
1449                TAG, "New death recipient " + this
1450                + " for thread " + thread.asBinder());
1451            mApp = app;
1452            mPid = pid;
1453            mAppThread = thread;
1454        }
1455
1456        @Override
1457        public void binderDied() {
1458            if (DEBUG_ALL) Slog.v(
1459                TAG, "Death received in " + this
1460                + " for thread " + mAppThread.asBinder());
1461            synchronized(ActivityManagerService.this) {
1462                appDiedLocked(mApp, mPid, mAppThread, true);
1463            }
1464        }
1465    }
1466
1467    static final int SHOW_ERROR_UI_MSG = 1;
1468    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1469    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1470    static final int UPDATE_CONFIGURATION_MSG = 4;
1471    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1472    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1473    static final int SERVICE_TIMEOUT_MSG = 12;
1474    static final int UPDATE_TIME_ZONE = 13;
1475    static final int SHOW_UID_ERROR_UI_MSG = 14;
1476    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1477    static final int PROC_START_TIMEOUT_MSG = 20;
1478    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1479    static final int KILL_APPLICATION_MSG = 22;
1480    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1481    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1482    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1483    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1484    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1485    static final int CLEAR_DNS_CACHE_MSG = 28;
1486    static final int UPDATE_HTTP_PROXY_MSG = 29;
1487    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1488    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1489    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1490    static final int REPORT_MEM_USAGE_MSG = 33;
1491    static final int REPORT_USER_SWITCH_MSG = 34;
1492    static final int CONTINUE_USER_SWITCH_MSG = 35;
1493    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1494    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1495    static final int PERSIST_URI_GRANTS_MSG = 38;
1496    static final int REQUEST_ALL_PSS_MSG = 39;
1497    static final int START_PROFILES_MSG = 40;
1498    static final int UPDATE_TIME = 41;
1499    static final int SYSTEM_USER_START_MSG = 42;
1500    static final int SYSTEM_USER_CURRENT_MSG = 43;
1501    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1502    static final int FINISH_BOOTING_MSG = 45;
1503    static final int START_USER_SWITCH_UI_MSG = 46;
1504    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1505    static final int DISMISS_DIALOG_UI_MSG = 48;
1506    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1507    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1508    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1509    static final int DELETE_DUMPHEAP_MSG = 52;
1510    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1511    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1512    static final int REPORT_TIME_TRACKER_MSG = 55;
1513    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1514    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1515    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1516    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1517    static final int IDLE_UIDS_MSG = 60;
1518    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1519    static final int LOG_STACK_STATE = 62;
1520    static final int VR_MODE_CHANGE_MSG = 63;
1521    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1522    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1523    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1524    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1525    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1526    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1527    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1528
1529    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1530    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1531    static final int FIRST_COMPAT_MODE_MSG = 300;
1532    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1533
1534    static ServiceThread sKillThread = null;
1535    static KillHandler sKillHandler = null;
1536
1537    CompatModeDialog mCompatModeDialog;
1538    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1539    long mLastMemUsageReportTime = 0;
1540
1541    /**
1542     * Flag whether the current user is a "monkey", i.e. whether
1543     * the UI is driven by a UI automation tool.
1544     */
1545    private boolean mUserIsMonkey;
1546
1547    /** Flag whether the device has a Recents UI */
1548    boolean mHasRecents;
1549
1550    /** The dimensions of the thumbnails in the Recents UI. */
1551    int mThumbnailWidth;
1552    int mThumbnailHeight;
1553    float mFullscreenThumbnailScale;
1554
1555    final ServiceThread mHandlerThread;
1556    final MainHandler mHandler;
1557    final UiHandler mUiHandler;
1558
1559    PackageManagerInternal mPackageManagerInt;
1560
1561    // VoiceInteraction session ID that changes for each new request except when
1562    // being called for multiwindow assist in a single session.
1563    private int mViSessionId = 1000;
1564
1565    final class KillHandler extends Handler {
1566        static final int KILL_PROCESS_GROUP_MSG = 4000;
1567
1568        public KillHandler(Looper looper) {
1569            super(looper, null, true);
1570        }
1571
1572        @Override
1573        public void handleMessage(Message msg) {
1574            switch (msg.what) {
1575                case KILL_PROCESS_GROUP_MSG:
1576                {
1577                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1578                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1579                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1580                }
1581                break;
1582
1583                default:
1584                    super.handleMessage(msg);
1585            }
1586        }
1587    }
1588
1589    final class UiHandler extends Handler {
1590        public UiHandler() {
1591            super(com.android.server.UiThread.get().getLooper(), null, true);
1592        }
1593
1594        @Override
1595        public void handleMessage(Message msg) {
1596            switch (msg.what) {
1597            case SHOW_ERROR_UI_MSG: {
1598                mAppErrors.handleShowAppErrorUi(msg);
1599                ensureBootCompleted();
1600            } break;
1601            case SHOW_NOT_RESPONDING_UI_MSG: {
1602                mAppErrors.handleShowAnrUi(msg);
1603                ensureBootCompleted();
1604            } break;
1605            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1606                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1607                synchronized (ActivityManagerService.this) {
1608                    ProcessRecord proc = (ProcessRecord) data.get("app");
1609                    if (proc == null) {
1610                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1611                        break;
1612                    }
1613                    if (proc.crashDialog != null) {
1614                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1615                        return;
1616                    }
1617                    AppErrorResult res = (AppErrorResult) data.get("result");
1618                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1619                        Dialog d = new StrictModeViolationDialog(mContext,
1620                                ActivityManagerService.this, res, proc);
1621                        d.show();
1622                        proc.crashDialog = d;
1623                    } else {
1624                        // The device is asleep, so just pretend that the user
1625                        // saw a crash dialog and hit "force quit".
1626                        res.set(0);
1627                    }
1628                }
1629                ensureBootCompleted();
1630            } break;
1631            case SHOW_FACTORY_ERROR_UI_MSG: {
1632                Dialog d = new FactoryErrorDialog(
1633                    mContext, msg.getData().getCharSequence("msg"));
1634                d.show();
1635                ensureBootCompleted();
1636            } break;
1637            case WAIT_FOR_DEBUGGER_UI_MSG: {
1638                synchronized (ActivityManagerService.this) {
1639                    ProcessRecord app = (ProcessRecord)msg.obj;
1640                    if (msg.arg1 != 0) {
1641                        if (!app.waitedForDebugger) {
1642                            Dialog d = new AppWaitingForDebuggerDialog(
1643                                    ActivityManagerService.this,
1644                                    mContext, app);
1645                            app.waitDialog = d;
1646                            app.waitedForDebugger = true;
1647                            d.show();
1648                        }
1649                    } else {
1650                        if (app.waitDialog != null) {
1651                            app.waitDialog.dismiss();
1652                            app.waitDialog = null;
1653                        }
1654                    }
1655                }
1656            } break;
1657            case SHOW_UID_ERROR_UI_MSG: {
1658                if (mShowDialogs) {
1659                    AlertDialog d = new BaseErrorDialog(mContext);
1660                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1661                    d.setCancelable(false);
1662                    d.setTitle(mContext.getText(R.string.android_system_label));
1663                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1664                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1665                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1666                    d.show();
1667                }
1668            } break;
1669            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1670                if (mShowDialogs) {
1671                    AlertDialog d = new BaseErrorDialog(mContext);
1672                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1673                    d.setCancelable(false);
1674                    d.setTitle(mContext.getText(R.string.android_system_label));
1675                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1676                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1677                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1678                    d.show();
1679                }
1680            } break;
1681            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    ActivityRecord ar = (ActivityRecord) msg.obj;
1684                    if (mCompatModeDialog != null) {
1685                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1686                                ar.info.applicationInfo.packageName)) {
1687                            return;
1688                        }
1689                        mCompatModeDialog.dismiss();
1690                        mCompatModeDialog = null;
1691                    }
1692                    if (ar != null && false) {
1693                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1694                                ar.packageName)) {
1695                            int mode = mCompatModePackages.computeCompatModeLocked(
1696                                    ar.info.applicationInfo);
1697                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1698                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1699                                mCompatModeDialog = new CompatModeDialog(
1700                                        ActivityManagerService.this, mContext,
1701                                        ar.info.applicationInfo);
1702                                mCompatModeDialog.show();
1703                            }
1704                        }
1705                    }
1706                }
1707                break;
1708            }
1709            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1710                synchronized (ActivityManagerService.this) {
1711                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1712                    if (mUnsupportedDisplaySizeDialog != null) {
1713                        mUnsupportedDisplaySizeDialog.dismiss();
1714                        mUnsupportedDisplaySizeDialog = null;
1715                    }
1716                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1717                            ar.packageName)) {
1718                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1719                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1720                        mUnsupportedDisplaySizeDialog.show();
1721                    }
1722                }
1723                break;
1724            }
1725            case START_USER_SWITCH_UI_MSG: {
1726                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1727                break;
1728            }
1729            case DISMISS_DIALOG_UI_MSG: {
1730                final Dialog d = (Dialog) msg.obj;
1731                d.dismiss();
1732                break;
1733            }
1734            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1735                dispatchProcessesChanged();
1736                break;
1737            }
1738            case DISPATCH_PROCESS_DIED_UI_MSG: {
1739                final int pid = msg.arg1;
1740                final int uid = msg.arg2;
1741                dispatchProcessDied(pid, uid);
1742                break;
1743            }
1744            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1745                dispatchUidsChanged();
1746            } break;
1747            }
1748        }
1749    }
1750
1751    final class MainHandler extends Handler {
1752        public MainHandler(Looper looper) {
1753            super(looper, null, true);
1754        }
1755
1756        @Override
1757        public void handleMessage(Message msg) {
1758            switch (msg.what) {
1759            case UPDATE_CONFIGURATION_MSG: {
1760                final ContentResolver resolver = mContext.getContentResolver();
1761                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1762                        msg.arg1);
1763            } break;
1764            case GC_BACKGROUND_PROCESSES_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    performAppGcsIfAppropriateLocked();
1767                }
1768            } break;
1769            case SERVICE_TIMEOUT_MSG: {
1770                if (mDidDexOpt) {
1771                    mDidDexOpt = false;
1772                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1773                    nmsg.obj = msg.obj;
1774                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1775                    return;
1776                }
1777                mServices.serviceTimeout((ProcessRecord)msg.obj);
1778            } break;
1779            case UPDATE_TIME_ZONE: {
1780                synchronized (ActivityManagerService.this) {
1781                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1782                        ProcessRecord r = mLruProcesses.get(i);
1783                        if (r.thread != null) {
1784                            try {
1785                                r.thread.updateTimeZone();
1786                            } catch (RemoteException ex) {
1787                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1788                            }
1789                        }
1790                    }
1791                }
1792            } break;
1793            case CLEAR_DNS_CACHE_MSG: {
1794                synchronized (ActivityManagerService.this) {
1795                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1796                        ProcessRecord r = mLruProcesses.get(i);
1797                        if (r.thread != null) {
1798                            try {
1799                                r.thread.clearDnsCache();
1800                            } catch (RemoteException ex) {
1801                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806            } break;
1807            case UPDATE_HTTP_PROXY_MSG: {
1808                ProxyInfo proxy = (ProxyInfo)msg.obj;
1809                String host = "";
1810                String port = "";
1811                String exclList = "";
1812                Uri pacFileUrl = Uri.EMPTY;
1813                if (proxy != null) {
1814                    host = proxy.getHost();
1815                    port = Integer.toString(proxy.getPort());
1816                    exclList = proxy.getExclusionListAsString();
1817                    pacFileUrl = proxy.getPacFileUrl();
1818                }
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.setHttpProxy(host, port, exclList, pacFileUrl);
1825                            } catch (RemoteException ex) {
1826                                Slog.w(TAG, "Failed to update http proxy for: " +
1827                                        r.info.processName);
1828                            }
1829                        }
1830                    }
1831                }
1832            } break;
1833            case PROC_START_TIMEOUT_MSG: {
1834                if (mDidDexOpt) {
1835                    mDidDexOpt = false;
1836                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1837                    nmsg.obj = msg.obj;
1838                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1839                    return;
1840                }
1841                ProcessRecord app = (ProcessRecord)msg.obj;
1842                synchronized (ActivityManagerService.this) {
1843                    processStartTimedOutLocked(app);
1844                }
1845            } break;
1846            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1847                ProcessRecord app = (ProcessRecord)msg.obj;
1848                synchronized (ActivityManagerService.this) {
1849                    processContentProviderPublishTimedOutLocked(app);
1850                }
1851            } break;
1852            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1855                }
1856            } break;
1857            case KILL_APPLICATION_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    final int appId = msg.arg1;
1860                    final int userId = msg.arg2;
1861                    Bundle bundle = (Bundle)msg.obj;
1862                    String pkg = bundle.getString("pkg");
1863                    String reason = bundle.getString("reason");
1864                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1865                            false, userId, reason);
1866                }
1867            } break;
1868            case FINALIZE_PENDING_INTENT_MSG: {
1869                ((PendingIntentRecord)msg.obj).completeFinalize();
1870            } break;
1871            case POST_HEAVY_NOTIFICATION_MSG: {
1872                INotificationManager inm = NotificationManager.getService();
1873                if (inm == null) {
1874                    return;
1875                }
1876
1877                ActivityRecord root = (ActivityRecord)msg.obj;
1878                ProcessRecord process = root.app;
1879                if (process == null) {
1880                    return;
1881                }
1882
1883                try {
1884                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1885                    String text = mContext.getString(R.string.heavy_weight_notification,
1886                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1887                    Notification notification = new Notification.Builder(context)
1888                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1889                            .setWhen(0)
1890                            .setOngoing(true)
1891                            .setTicker(text)
1892                            .setColor(mContext.getColor(
1893                                    com.android.internal.R.color.system_notification_accent_color))
1894                            .setContentTitle(text)
1895                            .setContentText(
1896                                    mContext.getText(R.string.heavy_weight_notification_detail))
1897                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1898                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1899                                    new UserHandle(root.userId)))
1900                            .build();
1901                    try {
1902                        int[] outId = new int[1];
1903                        inm.enqueueNotificationWithTag("android", "android", null,
1904                                R.string.heavy_weight_notification,
1905                                notification, outId, root.userId);
1906                    } catch (RuntimeException e) {
1907                        Slog.w(ActivityManagerService.TAG,
1908                                "Error showing notification for heavy-weight app", e);
1909                    } catch (RemoteException e) {
1910                    }
1911                } catch (NameNotFoundException e) {
1912                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1913                }
1914            } break;
1915            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1916                INotificationManager inm = NotificationManager.getService();
1917                if (inm == null) {
1918                    return;
1919                }
1920                try {
1921                    inm.cancelNotificationWithTag("android", null,
1922                            R.string.heavy_weight_notification,  msg.arg1);
1923                } catch (RuntimeException e) {
1924                    Slog.w(ActivityManagerService.TAG,
1925                            "Error canceling notification for service", e);
1926                } catch (RemoteException e) {
1927                }
1928            } break;
1929            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1930                synchronized (ActivityManagerService.this) {
1931                    checkExcessivePowerUsageLocked(true);
1932                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1933                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1934                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1935                }
1936            } break;
1937            case REPORT_MEM_USAGE_MSG: {
1938                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1939                Thread thread = new Thread() {
1940                    @Override public void run() {
1941                        reportMemUsage(memInfos);
1942                    }
1943                };
1944                thread.start();
1945                break;
1946            }
1947            case REPORT_USER_SWITCH_MSG: {
1948                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949                break;
1950            }
1951            case CONTINUE_USER_SWITCH_MSG: {
1952                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1953                break;
1954            }
1955            case USER_SWITCH_TIMEOUT_MSG: {
1956                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1957                break;
1958            }
1959            case IMMERSIVE_MODE_LOCK_MSG: {
1960                final boolean nextState = (msg.arg1 != 0);
1961                if (mUpdateLock.isHeld() != nextState) {
1962                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1963                            "Applying new update lock state '" + nextState
1964                            + "' for " + (ActivityRecord)msg.obj);
1965                    if (nextState) {
1966                        mUpdateLock.acquire();
1967                    } else {
1968                        mUpdateLock.release();
1969                    }
1970                }
1971                break;
1972            }
1973            case PERSIST_URI_GRANTS_MSG: {
1974                writeGrantedUriPermissions();
1975                break;
1976            }
1977            case REQUEST_ALL_PSS_MSG: {
1978                synchronized (ActivityManagerService.this) {
1979                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1980                }
1981                break;
1982            }
1983            case START_PROFILES_MSG: {
1984                synchronized (ActivityManagerService.this) {
1985                    mUserController.startProfilesLocked();
1986                }
1987                break;
1988            }
1989            case UPDATE_TIME: {
1990                synchronized (ActivityManagerService.this) {
1991                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1992                        ProcessRecord r = mLruProcesses.get(i);
1993                        if (r.thread != null) {
1994                            try {
1995                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1996                            } catch (RemoteException ex) {
1997                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1998                            }
1999                        }
2000                    }
2001                }
2002                break;
2003            }
2004            case SYSTEM_USER_START_MSG: {
2005                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2006                        Integer.toString(msg.arg1), msg.arg1);
2007                mSystemServiceManager.startUser(msg.arg1);
2008                break;
2009            }
2010            case SYSTEM_USER_UNLOCK_MSG: {
2011                final int userId = msg.arg1;
2012                mSystemServiceManager.unlockUser(userId);
2013                synchronized (ActivityManagerService.this) {
2014                    mRecentTasks.loadUserRecentsLocked(userId);
2015                }
2016                if (userId == UserHandle.USER_SYSTEM) {
2017                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2018                }
2019                installEncryptionUnawareProviders(userId);
2020                mUserController.finishUserUnlocked((UserState) msg.obj);
2021                break;
2022            }
2023            case SYSTEM_USER_CURRENT_MSG: {
2024                mBatteryStatsService.noteEvent(
2025                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2026                        Integer.toString(msg.arg2), msg.arg2);
2027                mBatteryStatsService.noteEvent(
2028                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2029                        Integer.toString(msg.arg1), msg.arg1);
2030                mSystemServiceManager.switchUser(msg.arg1);
2031                break;
2032            }
2033            case ENTER_ANIMATION_COMPLETE_MSG: {
2034                synchronized (ActivityManagerService.this) {
2035                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2036                    if (r != null && r.app != null && r.app.thread != null) {
2037                        try {
2038                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2039                        } catch (RemoteException e) {
2040                        }
2041                    }
2042                }
2043                break;
2044            }
2045            case FINISH_BOOTING_MSG: {
2046                if (msg.arg1 != 0) {
2047                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2048                    finishBooting();
2049                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2050                }
2051                if (msg.arg2 != 0) {
2052                    enableScreenAfterBoot();
2053                }
2054                break;
2055            }
2056            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2057                try {
2058                    Locale l = (Locale) msg.obj;
2059                    IBinder service = ServiceManager.getService("mount");
2060                    IMountService mountService = IMountService.Stub.asInterface(service);
2061                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2062                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2063                } catch (RemoteException e) {
2064                    Log.e(TAG, "Error storing locale for decryption UI", e);
2065                }
2066                break;
2067            }
2068            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2069                synchronized (ActivityManagerService.this) {
2070                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2071                        try {
2072                            // Make a one-way callback to the listener
2073                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2074                        } catch (RemoteException e){
2075                            // Handled by the RemoteCallbackList
2076                        }
2077                    }
2078                    mTaskStackListeners.finishBroadcast();
2079                }
2080                break;
2081            }
2082            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2083                synchronized (ActivityManagerService.this) {
2084                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2085                        try {
2086                            // Make a one-way callback to the listener
2087                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2088                        } catch (RemoteException e){
2089                            // Handled by the RemoteCallbackList
2090                        }
2091                    }
2092                    mTaskStackListeners.finishBroadcast();
2093                }
2094                break;
2095            }
2096            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2097                synchronized (ActivityManagerService.this) {
2098                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2099                        try {
2100                            // Make a one-way callback to the listener
2101                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2111                synchronized (ActivityManagerService.this) {
2112                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                        try {
2114                            // Make a one-way callback to the listener
2115                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2116                        } catch (RemoteException e){
2117                            // Handled by the RemoteCallbackList
2118                        }
2119                    }
2120                    mTaskStackListeners.finishBroadcast();
2121                }
2122                break;
2123            }
2124            case NOTIFY_FORCED_RESIZABLE_MSG: {
2125                synchronized (ActivityManagerService.this) {
2126                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2127                        try {
2128                            // Make a one-way callback to the listener
2129                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2130                                    (String) msg.obj, msg.arg1);
2131                        } catch (RemoteException e){
2132                            // Handled by the RemoteCallbackList
2133                        }
2134                    }
2135                    mTaskStackListeners.finishBroadcast();
2136                }
2137                break;
2138            }
2139                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2140                    synchronized (ActivityManagerService.this) {
2141                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2142                            try {
2143                                // Make a one-way callback to the listener
2144                                mTaskStackListeners.getBroadcastItem(i)
2145                                        .onActivityDismissingDockedStack();
2146                            } catch (RemoteException e){
2147                                // Handled by the RemoteCallbackList
2148                            }
2149                        }
2150                        mTaskStackListeners.finishBroadcast();
2151                    }
2152                    break;
2153                }
2154            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2155                final int uid = msg.arg1;
2156                final byte[] firstPacket = (byte[]) msg.obj;
2157
2158                synchronized (mPidsSelfLocked) {
2159                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2160                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2161                        if (p.uid == uid) {
2162                            try {
2163                                p.thread.notifyCleartextNetwork(firstPacket);
2164                            } catch (RemoteException ignored) {
2165                            }
2166                        }
2167                    }
2168                }
2169                break;
2170            }
2171            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2172                final String procName;
2173                final int uid;
2174                final long memLimit;
2175                final String reportPackage;
2176                synchronized (ActivityManagerService.this) {
2177                    procName = mMemWatchDumpProcName;
2178                    uid = mMemWatchDumpUid;
2179                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2180                    if (val == null) {
2181                        val = mMemWatchProcesses.get(procName, 0);
2182                    }
2183                    if (val != null) {
2184                        memLimit = val.first;
2185                        reportPackage = val.second;
2186                    } else {
2187                        memLimit = 0;
2188                        reportPackage = null;
2189                    }
2190                }
2191                if (procName == null) {
2192                    return;
2193                }
2194
2195                if (DEBUG_PSS) Slog.d(TAG_PSS,
2196                        "Showing dump heap notification from " + procName + "/" + uid);
2197
2198                INotificationManager inm = NotificationManager.getService();
2199                if (inm == null) {
2200                    return;
2201                }
2202
2203                String text = mContext.getString(R.string.dump_heap_notification, procName);
2204
2205
2206                Intent deleteIntent = new Intent();
2207                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2208                Intent intent = new Intent();
2209                intent.setClassName("android", DumpHeapActivity.class.getName());
2210                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2211                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2212                if (reportPackage != null) {
2213                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2214                }
2215                int userId = UserHandle.getUserId(uid);
2216                Notification notification = new Notification.Builder(mContext)
2217                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2218                        .setWhen(0)
2219                        .setOngoing(true)
2220                        .setAutoCancel(true)
2221                        .setTicker(text)
2222                        .setColor(mContext.getColor(
2223                                com.android.internal.R.color.system_notification_accent_color))
2224                        .setContentTitle(text)
2225                        .setContentText(
2226                                mContext.getText(R.string.dump_heap_notification_detail))
2227                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2228                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2229                                new UserHandle(userId)))
2230                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2231                                deleteIntent, 0, UserHandle.SYSTEM))
2232                        .build();
2233
2234                try {
2235                    int[] outId = new int[1];
2236                    inm.enqueueNotificationWithTag("android", "android", null,
2237                            R.string.dump_heap_notification,
2238                            notification, outId, userId);
2239                } catch (RuntimeException e) {
2240                    Slog.w(ActivityManagerService.TAG,
2241                            "Error showing notification for dump heap", e);
2242                } catch (RemoteException e) {
2243                }
2244            } break;
2245            case DELETE_DUMPHEAP_MSG: {
2246                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2247                        DumpHeapActivity.JAVA_URI,
2248                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2249                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2250                        UserHandle.myUserId());
2251                synchronized (ActivityManagerService.this) {
2252                    mMemWatchDumpFile = null;
2253                    mMemWatchDumpProcName = null;
2254                    mMemWatchDumpPid = -1;
2255                    mMemWatchDumpUid = -1;
2256                }
2257            } break;
2258            case FOREGROUND_PROFILE_CHANGED_MSG: {
2259                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2260            } break;
2261            case REPORT_TIME_TRACKER_MSG: {
2262                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2263                tracker.deliverResult(mContext);
2264            } break;
2265            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2266                mUserController.dispatchUserSwitchComplete(msg.arg1);
2267            } break;
2268            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2269                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2270                try {
2271                    connection.shutdown();
2272                } catch (RemoteException e) {
2273                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2274                }
2275                // Only a UiAutomation can set this flag and now that
2276                // it is finished we make sure it is reset to its default.
2277                mUserIsMonkey = false;
2278            } break;
2279            case APP_BOOST_DEACTIVATE_MSG: {
2280                synchronized(ActivityManagerService.this) {
2281                    if (mIsBoosted) {
2282                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2283                            nativeMigrateFromBoost();
2284                            mIsBoosted = false;
2285                            mBoostStartTime = 0;
2286                        } else {
2287                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2288                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2289                        }
2290                    }
2291                }
2292            } break;
2293            case IDLE_UIDS_MSG: {
2294                idleUids();
2295            } break;
2296            case LOG_STACK_STATE: {
2297                synchronized (ActivityManagerService.this) {
2298                    mStackSupervisor.logStackState();
2299                }
2300            } break;
2301            case VR_MODE_CHANGE_MSG: {
2302                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2303                final ActivityRecord r = (ActivityRecord) msg.obj;
2304                boolean vrMode;
2305                ComponentName requestedPackage;
2306                ComponentName callingPackage;
2307                int userId;
2308                synchronized (ActivityManagerService.this) {
2309                    vrMode = r.requestedVrComponent != null;
2310                    requestedPackage = r.requestedVrComponent;
2311                    userId = r.userId;
2312                    callingPackage = r.info.getComponentName();
2313                    if (mInVrMode != vrMode) {
2314                        mInVrMode = vrMode;
2315                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2316                        if (r.app != null) {
2317                            ProcessRecord proc = r.app;
2318                            if (proc.vrThreadTid > 0) {
2319                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2320                                    if (mInVrMode == true) {
2321                                        Process.setThreadScheduler(proc.vrThreadTid,
2322                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2323                                    } else {
2324                                        Process.setThreadScheduler(proc.vrThreadTid,
2325                                            Process.SCHED_OTHER, 0);
2326                                    }
2327                                }
2328                            }
2329                        }
2330                    }
2331                }
2332                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2333            } break;
2334            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2335                final ActivityRecord r = (ActivityRecord) msg.obj;
2336                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2337                if (needsVrMode) {
2338                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2339                            r.info.getComponentName(), false);
2340                }
2341            } break;
2342            }
2343        }
2344    };
2345
2346    static final int COLLECT_PSS_BG_MSG = 1;
2347
2348    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2349        @Override
2350        public void handleMessage(Message msg) {
2351            switch (msg.what) {
2352            case COLLECT_PSS_BG_MSG: {
2353                long start = SystemClock.uptimeMillis();
2354                MemInfoReader memInfo = null;
2355                synchronized (ActivityManagerService.this) {
2356                    if (mFullPssPending) {
2357                        mFullPssPending = false;
2358                        memInfo = new MemInfoReader();
2359                    }
2360                }
2361                if (memInfo != null) {
2362                    updateCpuStatsNow();
2363                    long nativeTotalPss = 0;
2364                    synchronized (mProcessCpuTracker) {
2365                        final int N = mProcessCpuTracker.countStats();
2366                        for (int j=0; j<N; j++) {
2367                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2368                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2369                                // This is definitely an application process; skip it.
2370                                continue;
2371                            }
2372                            synchronized (mPidsSelfLocked) {
2373                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2374                                    // This is one of our own processes; skip it.
2375                                    continue;
2376                                }
2377                            }
2378                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2379                        }
2380                    }
2381                    memInfo.readMemInfo();
2382                    synchronized (ActivityManagerService.this) {
2383                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2384                                + (SystemClock.uptimeMillis()-start) + "ms");
2385                        final long cachedKb = memInfo.getCachedSizeKb();
2386                        final long freeKb = memInfo.getFreeSizeKb();
2387                        final long zramKb = memInfo.getZramTotalSizeKb();
2388                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2389                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2390                                kernelKb*1024, nativeTotalPss*1024);
2391                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2392                                nativeTotalPss);
2393                    }
2394                }
2395
2396                int num = 0;
2397                long[] tmp = new long[2];
2398                do {
2399                    ProcessRecord proc;
2400                    int procState;
2401                    int pid;
2402                    long lastPssTime;
2403                    synchronized (ActivityManagerService.this) {
2404                        if (mPendingPssProcesses.size() <= 0) {
2405                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2406                                    "Collected PSS of " + num + " processes in "
2407                                    + (SystemClock.uptimeMillis() - start) + "ms");
2408                            mPendingPssProcesses.clear();
2409                            return;
2410                        }
2411                        proc = mPendingPssProcesses.remove(0);
2412                        procState = proc.pssProcState;
2413                        lastPssTime = proc.lastPssTime;
2414                        if (proc.thread != null && procState == proc.setProcState
2415                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2416                                        < SystemClock.uptimeMillis()) {
2417                            pid = proc.pid;
2418                        } else {
2419                            proc = null;
2420                            pid = 0;
2421                        }
2422                    }
2423                    if (proc != null) {
2424                        long pss = Debug.getPss(pid, tmp, null);
2425                        synchronized (ActivityManagerService.this) {
2426                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2427                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2428                                num++;
2429                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2430                                        SystemClock.uptimeMillis());
2431                            }
2432                        }
2433                    }
2434                } while (true);
2435            }
2436            }
2437        }
2438    };
2439
2440    public void setSystemProcess() {
2441        try {
2442            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2443            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2444            ServiceManager.addService("meminfo", new MemBinder(this));
2445            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2446            ServiceManager.addService("dbinfo", new DbBinder(this));
2447            if (MONITOR_CPU_USAGE) {
2448                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2449            }
2450            ServiceManager.addService("permission", new PermissionController(this));
2451            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2452
2453            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2454                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2455            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2456
2457            synchronized (this) {
2458                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2459                app.persistent = true;
2460                app.pid = MY_PID;
2461                app.maxAdj = ProcessList.SYSTEM_ADJ;
2462                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2463                synchronized (mPidsSelfLocked) {
2464                    mPidsSelfLocked.put(app.pid, app);
2465                }
2466                updateLruProcessLocked(app, false, null);
2467                updateOomAdjLocked();
2468            }
2469        } catch (PackageManager.NameNotFoundException e) {
2470            throw new RuntimeException(
2471                    "Unable to find android system package", e);
2472        }
2473    }
2474
2475    public void setWindowManager(WindowManagerService wm) {
2476        mWindowManager = wm;
2477        mStackSupervisor.setWindowManager(wm);
2478        mActivityStarter.setWindowManager(wm);
2479    }
2480
2481    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2482        mUsageStatsService = usageStatsManager;
2483    }
2484
2485    public void startObservingNativeCrashes() {
2486        final NativeCrashListener ncl = new NativeCrashListener(this);
2487        ncl.start();
2488    }
2489
2490    public IAppOpsService getAppOpsService() {
2491        return mAppOpsService;
2492    }
2493
2494    static class MemBinder extends Binder {
2495        ActivityManagerService mActivityManagerService;
2496        MemBinder(ActivityManagerService activityManagerService) {
2497            mActivityManagerService = activityManagerService;
2498        }
2499
2500        @Override
2501        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                    != PackageManager.PERMISSION_GRANTED) {
2504                pw.println("Permission Denial: can't dump meminfo from from pid="
2505                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                        + " without permission " + android.Manifest.permission.DUMP);
2507                return;
2508            }
2509
2510            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2511        }
2512    }
2513
2514    static class GraphicsBinder extends Binder {
2515        ActivityManagerService mActivityManagerService;
2516        GraphicsBinder(ActivityManagerService activityManagerService) {
2517            mActivityManagerService = activityManagerService;
2518        }
2519
2520        @Override
2521        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                    != PackageManager.PERMISSION_GRANTED) {
2524                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2525                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                        + " without permission " + android.Manifest.permission.DUMP);
2527                return;
2528            }
2529
2530            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2531        }
2532    }
2533
2534    static class DbBinder extends Binder {
2535        ActivityManagerService mActivityManagerService;
2536        DbBinder(ActivityManagerService activityManagerService) {
2537            mActivityManagerService = activityManagerService;
2538        }
2539
2540        @Override
2541        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2542            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2543                    != PackageManager.PERMISSION_GRANTED) {
2544                pw.println("Permission Denial: can't dump dbinfo from from pid="
2545                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2546                        + " without permission " + android.Manifest.permission.DUMP);
2547                return;
2548            }
2549
2550            mActivityManagerService.dumpDbInfo(fd, pw, args);
2551        }
2552    }
2553
2554    static class CpuBinder extends Binder {
2555        ActivityManagerService mActivityManagerService;
2556        CpuBinder(ActivityManagerService activityManagerService) {
2557            mActivityManagerService = activityManagerService;
2558        }
2559
2560        @Override
2561        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2562            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2563                    != PackageManager.PERMISSION_GRANTED) {
2564                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2565                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2566                        + " without permission " + android.Manifest.permission.DUMP);
2567                return;
2568            }
2569
2570            synchronized (mActivityManagerService.mProcessCpuTracker) {
2571                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2572                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2573                        SystemClock.uptimeMillis()));
2574            }
2575        }
2576    }
2577
2578    public static final class Lifecycle extends SystemService {
2579        private final ActivityManagerService mService;
2580
2581        public Lifecycle(Context context) {
2582            super(context);
2583            mService = new ActivityManagerService(context);
2584        }
2585
2586        @Override
2587        public void onStart() {
2588            mService.start();
2589        }
2590
2591        public ActivityManagerService getService() {
2592            return mService;
2593        }
2594    }
2595
2596    // Note: This method is invoked on the main thread but may need to attach various
2597    // handlers to other threads.  So take care to be explicit about the looper.
2598    public ActivityManagerService(Context systemContext) {
2599        mContext = systemContext;
2600        mFactoryTest = FactoryTest.getMode();
2601        mSystemThread = ActivityThread.currentActivityThread();
2602
2603        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2604
2605        mHandlerThread = new ServiceThread(TAG,
2606                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2607        mHandlerThread.start();
2608        mHandler = new MainHandler(mHandlerThread.getLooper());
2609        mUiHandler = new UiHandler();
2610
2611        /* static; one-time init here */
2612        if (sKillHandler == null) {
2613            sKillThread = new ServiceThread(TAG + ":kill",
2614                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2615            sKillThread.start();
2616            sKillHandler = new KillHandler(sKillThread.getLooper());
2617        }
2618
2619        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2620                "foreground", BROADCAST_FG_TIMEOUT, false);
2621        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2622                "background", BROADCAST_BG_TIMEOUT, true);
2623        mBroadcastQueues[0] = mFgBroadcastQueue;
2624        mBroadcastQueues[1] = mBgBroadcastQueue;
2625
2626        mServices = new ActiveServices(this);
2627        mProviderMap = new ProviderMap(this);
2628        mAppErrors = new AppErrors(mContext, this);
2629
2630        // TODO: Move creation of battery stats service outside of activity manager service.
2631        File dataDir = Environment.getDataDirectory();
2632        File systemDir = new File(dataDir, "system");
2633        systemDir.mkdirs();
2634        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2635        mBatteryStatsService.getActiveStatistics().readLocked();
2636        mBatteryStatsService.scheduleWriteToDisk();
2637        mOnBattery = DEBUG_POWER ? true
2638                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2639        mBatteryStatsService.getActiveStatistics().setCallback(this);
2640
2641        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2642
2643        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2644        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2645                new IAppOpsCallback.Stub() {
2646                    @Override public void opChanged(int op, int uid, String packageName) {
2647                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2648                            if (mAppOpsService.checkOperation(op, uid, packageName)
2649                                    != AppOpsManager.MODE_ALLOWED) {
2650                                runInBackgroundDisabled(uid);
2651                            }
2652                        }
2653                    }
2654                });
2655
2656        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2657
2658        mUserController = new UserController(this);
2659
2660        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2661            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2662
2663        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2664            mUseFifoUiScheduling = true;
2665        }
2666
2667        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2668
2669        mConfiguration.setToDefaults();
2670        mConfiguration.setLocales(LocaleList.getDefault());
2671
2672        mConfigurationSeq = mConfiguration.seq = 1;
2673        mProcessCpuTracker.init();
2674
2675        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2676        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2677        mStackSupervisor = new ActivityStackSupervisor(this);
2678        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2679        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2680
2681        mProcessCpuThread = new Thread("CpuTracker") {
2682            @Override
2683            public void run() {
2684                while (true) {
2685                    try {
2686                        try {
2687                            synchronized(this) {
2688                                final long now = SystemClock.uptimeMillis();
2689                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2690                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2691                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2692                                //        + ", write delay=" + nextWriteDelay);
2693                                if (nextWriteDelay < nextCpuDelay) {
2694                                    nextCpuDelay = nextWriteDelay;
2695                                }
2696                                if (nextCpuDelay > 0) {
2697                                    mProcessCpuMutexFree.set(true);
2698                                    this.wait(nextCpuDelay);
2699                                }
2700                            }
2701                        } catch (InterruptedException e) {
2702                        }
2703                        updateCpuStatsNow();
2704                    } catch (Exception e) {
2705                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2706                    }
2707                }
2708            }
2709        };
2710
2711        Watchdog.getInstance().addMonitor(this);
2712        Watchdog.getInstance().addThread(mHandler);
2713    }
2714
2715    public void setSystemServiceManager(SystemServiceManager mgr) {
2716        mSystemServiceManager = mgr;
2717    }
2718
2719    public void setInstaller(Installer installer) {
2720        mInstaller = installer;
2721    }
2722
2723    private void start() {
2724        Process.removeAllProcessGroups();
2725        mProcessCpuThread.start();
2726
2727        mBatteryStatsService.publish(mContext);
2728        mAppOpsService.publish(mContext);
2729        Slog.d("AppOps", "AppOpsService published");
2730        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2731    }
2732
2733    void onUserStoppedLocked(int userId) {
2734        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2735    }
2736
2737    public void initPowerManagement() {
2738        mStackSupervisor.initPowerManagement();
2739        mBatteryStatsService.initPowerManagement();
2740        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2741        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2742        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2743        mVoiceWakeLock.setReferenceCounted(false);
2744    }
2745
2746    @Override
2747    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2748            throws RemoteException {
2749        if (code == SYSPROPS_TRANSACTION) {
2750            // We need to tell all apps about the system property change.
2751            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2752            synchronized(this) {
2753                final int NP = mProcessNames.getMap().size();
2754                for (int ip=0; ip<NP; ip++) {
2755                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2756                    final int NA = apps.size();
2757                    for (int ia=0; ia<NA; ia++) {
2758                        ProcessRecord app = apps.valueAt(ia);
2759                        if (app.thread != null) {
2760                            procs.add(app.thread.asBinder());
2761                        }
2762                    }
2763                }
2764            }
2765
2766            int N = procs.size();
2767            for (int i=0; i<N; i++) {
2768                Parcel data2 = Parcel.obtain();
2769                try {
2770                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2771                } catch (RemoteException e) {
2772                }
2773                data2.recycle();
2774            }
2775        }
2776        try {
2777            return super.onTransact(code, data, reply, flags);
2778        } catch (RuntimeException e) {
2779            // The activity manager only throws security exceptions, so let's
2780            // log all others.
2781            if (!(e instanceof SecurityException)) {
2782                Slog.wtf(TAG, "Activity Manager Crash", e);
2783            }
2784            throw e;
2785        }
2786    }
2787
2788    void updateCpuStats() {
2789        final long now = SystemClock.uptimeMillis();
2790        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2791            return;
2792        }
2793        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2794            synchronized (mProcessCpuThread) {
2795                mProcessCpuThread.notify();
2796            }
2797        }
2798    }
2799
2800    void updateCpuStatsNow() {
2801        synchronized (mProcessCpuTracker) {
2802            mProcessCpuMutexFree.set(false);
2803            final long now = SystemClock.uptimeMillis();
2804            boolean haveNewCpuStats = false;
2805
2806            if (MONITOR_CPU_USAGE &&
2807                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2808                mLastCpuTime.set(now);
2809                mProcessCpuTracker.update();
2810                if (mProcessCpuTracker.hasGoodLastStats()) {
2811                    haveNewCpuStats = true;
2812                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2813                    //Slog.i(TAG, "Total CPU usage: "
2814                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2815
2816                    // Slog the cpu usage if the property is set.
2817                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2818                        int user = mProcessCpuTracker.getLastUserTime();
2819                        int system = mProcessCpuTracker.getLastSystemTime();
2820                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2821                        int irq = mProcessCpuTracker.getLastIrqTime();
2822                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2823                        int idle = mProcessCpuTracker.getLastIdleTime();
2824
2825                        int total = user + system + iowait + irq + softIrq + idle;
2826                        if (total == 0) total = 1;
2827
2828                        EventLog.writeEvent(EventLogTags.CPU,
2829                                ((user+system+iowait+irq+softIrq) * 100) / total,
2830                                (user * 100) / total,
2831                                (system * 100) / total,
2832                                (iowait * 100) / total,
2833                                (irq * 100) / total,
2834                                (softIrq * 100) / total);
2835                    }
2836                }
2837            }
2838
2839            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2840            synchronized(bstats) {
2841                synchronized(mPidsSelfLocked) {
2842                    if (haveNewCpuStats) {
2843                        if (bstats.startAddingCpuLocked()) {
2844                            int totalUTime = 0;
2845                            int totalSTime = 0;
2846                            final int N = mProcessCpuTracker.countStats();
2847                            for (int i=0; i<N; i++) {
2848                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2849                                if (!st.working) {
2850                                    continue;
2851                                }
2852                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2853                                totalUTime += st.rel_utime;
2854                                totalSTime += st.rel_stime;
2855                                if (pr != null) {
2856                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2857                                    if (ps == null || !ps.isActive()) {
2858                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2859                                                pr.info.uid, pr.processName);
2860                                    }
2861                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2862                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2863                                } else {
2864                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2865                                    if (ps == null || !ps.isActive()) {
2866                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2867                                                bstats.mapUid(st.uid), st.name);
2868                                    }
2869                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2870                                }
2871                            }
2872                            final int userTime = mProcessCpuTracker.getLastUserTime();
2873                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2874                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2875                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2876                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2877                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2878                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2879                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2880                        }
2881                    }
2882                }
2883
2884                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2885                    mLastWriteTime = now;
2886                    mBatteryStatsService.scheduleWriteToDisk();
2887                }
2888            }
2889        }
2890    }
2891
2892    @Override
2893    public void batteryNeedsCpuUpdate() {
2894        updateCpuStatsNow();
2895    }
2896
2897    @Override
2898    public void batteryPowerChanged(boolean onBattery) {
2899        // When plugging in, update the CPU stats first before changing
2900        // the plug state.
2901        updateCpuStatsNow();
2902        synchronized (this) {
2903            synchronized(mPidsSelfLocked) {
2904                mOnBattery = DEBUG_POWER ? true : onBattery;
2905            }
2906        }
2907    }
2908
2909    @Override
2910    public void batterySendBroadcast(Intent intent) {
2911        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2912                AppOpsManager.OP_NONE, null, false, false,
2913                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2914    }
2915
2916    /**
2917     * Initialize the application bind args. These are passed to each
2918     * process when the bindApplication() IPC is sent to the process. They're
2919     * lazily setup to make sure the services are running when they're asked for.
2920     */
2921    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2922        if (mAppBindArgs == null) {
2923            mAppBindArgs = new HashMap<>();
2924
2925            // Isolated processes won't get this optimization, so that we don't
2926            // violate the rules about which services they have access to.
2927            if (!isolated) {
2928                // Setup the application init args
2929                mAppBindArgs.put("package", ServiceManager.getService("package"));
2930                mAppBindArgs.put("window", ServiceManager.getService("window"));
2931                mAppBindArgs.put(Context.ALARM_SERVICE,
2932                        ServiceManager.getService(Context.ALARM_SERVICE));
2933            }
2934        }
2935        return mAppBindArgs;
2936    }
2937
2938    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2939        if (r == null || mFocusedActivity == r) {
2940            return false;
2941        }
2942
2943        if (!r.isFocusable()) {
2944            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2945            return false;
2946        }
2947
2948        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2949
2950        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2951        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2952                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2953        mDoingSetFocusedActivity = true;
2954
2955        final ActivityRecord last = mFocusedActivity;
2956        mFocusedActivity = r;
2957        if (r.task.isApplicationTask()) {
2958            if (mCurAppTimeTracker != r.appTimeTracker) {
2959                // We are switching app tracking.  Complete the current one.
2960                if (mCurAppTimeTracker != null) {
2961                    mCurAppTimeTracker.stop();
2962                    mHandler.obtainMessage(
2963                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2964                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2965                    mCurAppTimeTracker = null;
2966                }
2967                if (r.appTimeTracker != null) {
2968                    mCurAppTimeTracker = r.appTimeTracker;
2969                    startTimeTrackingFocusedActivityLocked();
2970                }
2971            } else {
2972                startTimeTrackingFocusedActivityLocked();
2973            }
2974        } else {
2975            r.appTimeTracker = null;
2976        }
2977        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2978        // TODO: Probably not, because we don't want to resume voice on switching
2979        // back to this activity
2980        if (r.task.voiceInteractor != null) {
2981            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2982        } else {
2983            finishRunningVoiceLocked();
2984            IVoiceInteractionSession session;
2985            if (last != null && ((session = last.task.voiceSession) != null
2986                    || (session = last.voiceSession) != null)) {
2987                // We had been in a voice interaction session, but now focused has
2988                // move to something different.  Just finish the session, we can't
2989                // return to it and retain the proper state and synchronization with
2990                // the voice interaction service.
2991                finishVoiceTask(session);
2992            }
2993        }
2994        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2995            mWindowManager.setFocusedApp(r.appToken, true);
2996        }
2997        applyUpdateLockStateLocked(r);
2998        applyUpdateVrModeLocked(r);
2999        if (mFocusedActivity.userId != mLastFocusedUserId) {
3000            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3001            mHandler.obtainMessage(
3002                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3003            mLastFocusedUserId = mFocusedActivity.userId;
3004        }
3005
3006        // Log a warning if the focused app is changed during the process. This could
3007        // indicate a problem of the focus setting logic!
3008        if (mFocusedActivity != r) Slog.w(TAG,
3009                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3010        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3011
3012        EventLogTags.writeAmFocusedActivity(
3013                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3014                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3015                reason);
3016        return true;
3017    }
3018
3019    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3020        if (mFocusedActivity != goingAway) {
3021            return;
3022        }
3023
3024        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3025        if (focusedStack != null) {
3026            final ActivityRecord top = focusedStack.topActivity();
3027            if (top != null && top.userId != mLastFocusedUserId) {
3028                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3029                mHandler.sendMessage(
3030                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3031                mLastFocusedUserId = top.userId;
3032            }
3033        }
3034
3035        // Try to move focus to another activity if possible.
3036        if (setFocusedActivityLocked(
3037                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3038            return;
3039        }
3040
3041        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3042                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3043        mFocusedActivity = null;
3044        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3045    }
3046
3047    @Override
3048    public void setFocusedStack(int stackId) {
3049        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3050        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3051        final long callingId = Binder.clearCallingIdentity();
3052        try {
3053            synchronized (this) {
3054                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3055                if (stack == null) {
3056                    return;
3057                }
3058                final ActivityRecord r = stack.topRunningActivityLocked();
3059                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3060                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3061                }
3062            }
3063        } finally {
3064            Binder.restoreCallingIdentity(callingId);
3065        }
3066    }
3067
3068    @Override
3069    public void setFocusedTask(int taskId) {
3070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3071        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3072        final long callingId = Binder.clearCallingIdentity();
3073        try {
3074            synchronized (this) {
3075                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3076                if (task == null) {
3077                    return;
3078                }
3079                final ActivityRecord r = task.topRunningActivityLocked();
3080                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3081                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3082                }
3083            }
3084        } finally {
3085            Binder.restoreCallingIdentity(callingId);
3086        }
3087    }
3088
3089    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3090    @Override
3091    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3092        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3093        synchronized (this) {
3094            if (listener != null) {
3095                mTaskStackListeners.register(listener);
3096            }
3097        }
3098    }
3099
3100    @Override
3101    public void notifyActivityDrawn(IBinder token) {
3102        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3103        synchronized (this) {
3104            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3105            if (r != null) {
3106                r.task.stack.notifyActivityDrawnLocked(r);
3107            }
3108        }
3109    }
3110
3111    final void applyUpdateLockStateLocked(ActivityRecord r) {
3112        // Modifications to the UpdateLock state are done on our handler, outside
3113        // the activity manager's locks.  The new state is determined based on the
3114        // state *now* of the relevant activity record.  The object is passed to
3115        // the handler solely for logging detail, not to be consulted/modified.
3116        final boolean nextState = r != null && r.immersive;
3117        mHandler.sendMessage(
3118                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3119    }
3120
3121    final void applyUpdateVrModeLocked(ActivityRecord r) {
3122        mHandler.sendMessage(
3123                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3124    }
3125
3126    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3127        mHandler.sendMessage(
3128                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3129    }
3130
3131    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3132            ComponentName callingPackage, boolean immediate) {
3133        VrManagerInternal vrService =
3134                LocalServices.getService(VrManagerInternal.class);
3135        if (immediate) {
3136            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3137        } else {
3138            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3139        }
3140    }
3141
3142    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3143        Message msg = Message.obtain();
3144        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3145        msg.obj = r.task.askedCompatMode ? null : r;
3146        mUiHandler.sendMessage(msg);
3147    }
3148
3149    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3150        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3151                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3152            final Message msg = Message.obtain();
3153            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3154            msg.obj = r;
3155            mUiHandler.sendMessage(msg);
3156        }
3157    }
3158
3159    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3160            String what, Object obj, ProcessRecord srcApp) {
3161        app.lastActivityTime = now;
3162
3163        if (app.activities.size() > 0) {
3164            // Don't want to touch dependent processes that are hosting activities.
3165            return index;
3166        }
3167
3168        int lrui = mLruProcesses.lastIndexOf(app);
3169        if (lrui < 0) {
3170            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3171                    + what + " " + obj + " from " + srcApp);
3172            return index;
3173        }
3174
3175        if (lrui >= index) {
3176            // Don't want to cause this to move dependent processes *back* in the
3177            // list as if they were less frequently used.
3178            return index;
3179        }
3180
3181        if (lrui >= mLruProcessActivityStart) {
3182            // Don't want to touch dependent processes that are hosting activities.
3183            return index;
3184        }
3185
3186        mLruProcesses.remove(lrui);
3187        if (index > 0) {
3188            index--;
3189        }
3190        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3191                + " in LRU list: " + app);
3192        mLruProcesses.add(index, app);
3193        return index;
3194    }
3195
3196    static void killProcessGroup(int uid, int pid) {
3197        if (sKillHandler != null) {
3198            sKillHandler.sendMessage(
3199                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3200        } else {
3201            Slog.w(TAG, "Asked to kill process group before system bringup!");
3202            Process.killProcessGroup(uid, pid);
3203        }
3204    }
3205
3206    final void removeLruProcessLocked(ProcessRecord app) {
3207        int lrui = mLruProcesses.lastIndexOf(app);
3208        if (lrui >= 0) {
3209            if (!app.killed) {
3210                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3211                Process.killProcessQuiet(app.pid);
3212                killProcessGroup(app.uid, app.pid);
3213            }
3214            if (lrui <= mLruProcessActivityStart) {
3215                mLruProcessActivityStart--;
3216            }
3217            if (lrui <= mLruProcessServiceStart) {
3218                mLruProcessServiceStart--;
3219            }
3220            mLruProcesses.remove(lrui);
3221        }
3222    }
3223
3224    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3225            ProcessRecord client) {
3226        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3227                || app.treatLikeActivity;
3228        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3229        if (!activityChange && hasActivity) {
3230            // The process has activities, so we are only allowing activity-based adjustments
3231            // to move it.  It should be kept in the front of the list with other
3232            // processes that have activities, and we don't want those to change their
3233            // order except due to activity operations.
3234            return;
3235        }
3236
3237        mLruSeq++;
3238        final long now = SystemClock.uptimeMillis();
3239        app.lastActivityTime = now;
3240
3241        // First a quick reject: if the app is already at the position we will
3242        // put it, then there is nothing to do.
3243        if (hasActivity) {
3244            final int N = mLruProcesses.size();
3245            if (N > 0 && mLruProcesses.get(N-1) == app) {
3246                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3247                return;
3248            }
3249        } else {
3250            if (mLruProcessServiceStart > 0
3251                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3252                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3253                return;
3254            }
3255        }
3256
3257        int lrui = mLruProcesses.lastIndexOf(app);
3258
3259        if (app.persistent && lrui >= 0) {
3260            // We don't care about the position of persistent processes, as long as
3261            // they are in the list.
3262            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3263            return;
3264        }
3265
3266        /* In progress: compute new position first, so we can avoid doing work
3267           if the process is not actually going to move.  Not yet working.
3268        int addIndex;
3269        int nextIndex;
3270        boolean inActivity = false, inService = false;
3271        if (hasActivity) {
3272            // Process has activities, put it at the very tipsy-top.
3273            addIndex = mLruProcesses.size();
3274            nextIndex = mLruProcessServiceStart;
3275            inActivity = true;
3276        } else if (hasService) {
3277            // Process has services, put it at the top of the service list.
3278            addIndex = mLruProcessActivityStart;
3279            nextIndex = mLruProcessServiceStart;
3280            inActivity = true;
3281            inService = true;
3282        } else  {
3283            // Process not otherwise of interest, it goes to the top of the non-service area.
3284            addIndex = mLruProcessServiceStart;
3285            if (client != null) {
3286                int clientIndex = mLruProcesses.lastIndexOf(client);
3287                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3288                        + app);
3289                if (clientIndex >= 0 && addIndex > clientIndex) {
3290                    addIndex = clientIndex;
3291                }
3292            }
3293            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3294        }
3295
3296        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3297                + mLruProcessActivityStart + "): " + app);
3298        */
3299
3300        if (lrui >= 0) {
3301            if (lrui < mLruProcessActivityStart) {
3302                mLruProcessActivityStart--;
3303            }
3304            if (lrui < mLruProcessServiceStart) {
3305                mLruProcessServiceStart--;
3306            }
3307            /*
3308            if (addIndex > lrui) {
3309                addIndex--;
3310            }
3311            if (nextIndex > lrui) {
3312                nextIndex--;
3313            }
3314            */
3315            mLruProcesses.remove(lrui);
3316        }
3317
3318        /*
3319        mLruProcesses.add(addIndex, app);
3320        if (inActivity) {
3321            mLruProcessActivityStart++;
3322        }
3323        if (inService) {
3324            mLruProcessActivityStart++;
3325        }
3326        */
3327
3328        int nextIndex;
3329        if (hasActivity) {
3330            final int N = mLruProcesses.size();
3331            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3332                // Process doesn't have activities, but has clients with
3333                // activities...  move it up, but one below the top (the top
3334                // should always have a real activity).
3335                if (DEBUG_LRU) Slog.d(TAG_LRU,
3336                        "Adding to second-top of LRU activity list: " + app);
3337                mLruProcesses.add(N - 1, app);
3338                // To keep it from spamming the LRU list (by making a bunch of clients),
3339                // we will push down any other entries owned by the app.
3340                final int uid = app.info.uid;
3341                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3342                    ProcessRecord subProc = mLruProcesses.get(i);
3343                    if (subProc.info.uid == uid) {
3344                        // We want to push this one down the list.  If the process after
3345                        // it is for the same uid, however, don't do so, because we don't
3346                        // want them internally to be re-ordered.
3347                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3348                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3349                                    "Pushing uid " + uid + " swapping at " + i + ": "
3350                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3351                            ProcessRecord tmp = mLruProcesses.get(i);
3352                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3353                            mLruProcesses.set(i - 1, tmp);
3354                            i--;
3355                        }
3356                    } else {
3357                        // A gap, we can stop here.
3358                        break;
3359                    }
3360                }
3361            } else {
3362                // Process has activities, put it at the very tipsy-top.
3363                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3364                mLruProcesses.add(app);
3365            }
3366            nextIndex = mLruProcessServiceStart;
3367        } else if (hasService) {
3368            // Process has services, put it at the top of the service list.
3369            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3370            mLruProcesses.add(mLruProcessActivityStart, app);
3371            nextIndex = mLruProcessServiceStart;
3372            mLruProcessActivityStart++;
3373        } else  {
3374            // Process not otherwise of interest, it goes to the top of the non-service area.
3375            int index = mLruProcessServiceStart;
3376            if (client != null) {
3377                // If there is a client, don't allow the process to be moved up higher
3378                // in the list than that client.
3379                int clientIndex = mLruProcesses.lastIndexOf(client);
3380                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3381                        + " when updating " + app);
3382                if (clientIndex <= lrui) {
3383                    // Don't allow the client index restriction to push it down farther in the
3384                    // list than it already is.
3385                    clientIndex = lrui;
3386                }
3387                if (clientIndex >= 0 && index > clientIndex) {
3388                    index = clientIndex;
3389                }
3390            }
3391            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3392            mLruProcesses.add(index, app);
3393            nextIndex = index-1;
3394            mLruProcessActivityStart++;
3395            mLruProcessServiceStart++;
3396        }
3397
3398        // If the app is currently using a content provider or service,
3399        // bump those processes as well.
3400        for (int j=app.connections.size()-1; j>=0; j--) {
3401            ConnectionRecord cr = app.connections.valueAt(j);
3402            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3403                    && cr.binding.service.app != null
3404                    && cr.binding.service.app.lruSeq != mLruSeq
3405                    && !cr.binding.service.app.persistent) {
3406                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3407                        "service connection", cr, app);
3408            }
3409        }
3410        for (int j=app.conProviders.size()-1; j>=0; j--) {
3411            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3412            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3413                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3414                        "provider reference", cpr, app);
3415            }
3416        }
3417    }
3418
3419    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3420        if (uid == Process.SYSTEM_UID) {
3421            // The system gets to run in any process.  If there are multiple
3422            // processes with the same uid, just pick the first (this
3423            // should never happen).
3424            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3425            if (procs == null) return null;
3426            final int procCount = procs.size();
3427            for (int i = 0; i < procCount; i++) {
3428                final int procUid = procs.keyAt(i);
3429                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3430                    // Don't use an app process or different user process for system component.
3431                    continue;
3432                }
3433                return procs.valueAt(i);
3434            }
3435        }
3436        ProcessRecord proc = mProcessNames.get(processName, uid);
3437        if (false && proc != null && !keepIfLarge
3438                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3439                && proc.lastCachedPss >= 4000) {
3440            // Turn this condition on to cause killing to happen regularly, for testing.
3441            if (proc.baseProcessTracker != null) {
3442                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3443            }
3444            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3445        } else if (proc != null && !keepIfLarge
3446                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3447                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3448            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3449            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3450                if (proc.baseProcessTracker != null) {
3451                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3452                }
3453                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3454            }
3455        }
3456        return proc;
3457    }
3458
3459    void notifyPackageUse(String packageName, int reason) {
3460        IPackageManager pm = AppGlobals.getPackageManager();
3461        try {
3462            pm.notifyPackageUse(packageName, reason);
3463        } catch (RemoteException e) {
3464        }
3465    }
3466
3467    boolean isNextTransitionForward() {
3468        int transit = mWindowManager.getPendingAppTransition();
3469        return transit == TRANSIT_ACTIVITY_OPEN
3470                || transit == TRANSIT_TASK_OPEN
3471                || transit == TRANSIT_TASK_TO_FRONT;
3472    }
3473
3474    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3475            String processName, String abiOverride, int uid, Runnable crashHandler) {
3476        synchronized(this) {
3477            ApplicationInfo info = new ApplicationInfo();
3478            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3479            // For isolated processes, the former contains the parent's uid and the latter the
3480            // actual uid of the isolated process.
3481            // In the special case introduced by this method (which is, starting an isolated
3482            // process directly from the SystemServer without an actual parent app process) the
3483            // closest thing to a parent's uid is SYSTEM_UID.
3484            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3485            // the |isolated| logic in the ProcessRecord constructor.
3486            info.uid = Process.SYSTEM_UID;
3487            info.processName = processName;
3488            info.className = entryPoint;
3489            info.packageName = "android";
3490            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3491                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3492                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3493                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3494                    crashHandler);
3495            return proc != null ? proc.pid : 0;
3496        }
3497    }
3498
3499    final ProcessRecord startProcessLocked(String processName,
3500            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3501            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3502            boolean isolated, boolean keepIfLarge) {
3503        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3504                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3505                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3506                null /* crashHandler */);
3507    }
3508
3509    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3510            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3511            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3512            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3513        long startTime = SystemClock.elapsedRealtime();
3514        ProcessRecord app;
3515        if (!isolated) {
3516            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3517            checkTime(startTime, "startProcess: after getProcessRecord");
3518
3519            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3520                // If we are in the background, then check to see if this process
3521                // is bad.  If so, we will just silently fail.
3522                if (mAppErrors.isBadProcessLocked(info)) {
3523                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3524                            + "/" + info.processName);
3525                    return null;
3526                }
3527            } else {
3528                // When the user is explicitly starting a process, then clear its
3529                // crash count so that we won't make it bad until they see at
3530                // least one crash dialog again, and make the process good again
3531                // if it had been bad.
3532                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3533                        + "/" + info.processName);
3534                mAppErrors.resetProcessCrashTimeLocked(info);
3535                if (mAppErrors.isBadProcessLocked(info)) {
3536                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3537                            UserHandle.getUserId(info.uid), info.uid,
3538                            info.processName);
3539                    mAppErrors.clearBadProcessLocked(info);
3540                    if (app != null) {
3541                        app.bad = false;
3542                    }
3543                }
3544            }
3545        } else {
3546            // If this is an isolated process, it can't re-use an existing process.
3547            app = null;
3548        }
3549
3550        // app launch boost for big.little configurations
3551        // use cpusets to migrate freshly launched tasks to big cores
3552        nativeMigrateToBoost();
3553        mIsBoosted = true;
3554        mBoostStartTime = SystemClock.uptimeMillis();
3555        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3556        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3557
3558        // We don't have to do anything more if:
3559        // (1) There is an existing application record; and
3560        // (2) The caller doesn't think it is dead, OR there is no thread
3561        //     object attached to it so we know it couldn't have crashed; and
3562        // (3) There is a pid assigned to it, so it is either starting or
3563        //     already running.
3564        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3565                + " app=" + app + " knownToBeDead=" + knownToBeDead
3566                + " thread=" + (app != null ? app.thread : null)
3567                + " pid=" + (app != null ? app.pid : -1));
3568        if (app != null && app.pid > 0) {
3569            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3570                // We already have the app running, or are waiting for it to
3571                // come up (we have a pid but not yet its thread), so keep it.
3572                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3573                // If this is a new package in the process, add the package to the list
3574                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3575                checkTime(startTime, "startProcess: done, added package to proc");
3576                return app;
3577            }
3578
3579            // An application record is attached to a previous process,
3580            // clean it up now.
3581            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3582            checkTime(startTime, "startProcess: bad proc running, killing");
3583            killProcessGroup(app.uid, app.pid);
3584            handleAppDiedLocked(app, true, true);
3585            checkTime(startTime, "startProcess: done killing old proc");
3586        }
3587
3588        String hostingNameStr = hostingName != null
3589                ? hostingName.flattenToShortString() : null;
3590
3591        if (app == null) {
3592            checkTime(startTime, "startProcess: creating new process record");
3593            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3594            if (app == null) {
3595                Slog.w(TAG, "Failed making new process record for "
3596                        + processName + "/" + info.uid + " isolated=" + isolated);
3597                return null;
3598            }
3599            app.crashHandler = crashHandler;
3600            checkTime(startTime, "startProcess: done creating new process record");
3601        } else {
3602            // If this is a new package in the process, add the package to the list
3603            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3604            checkTime(startTime, "startProcess: added package to existing proc");
3605        }
3606
3607        // If the system is not ready yet, then hold off on starting this
3608        // process until it is.
3609        if (!mProcessesReady
3610                && !isAllowedWhileBooting(info)
3611                && !allowWhileBooting) {
3612            if (!mProcessesOnHold.contains(app)) {
3613                mProcessesOnHold.add(app);
3614            }
3615            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3616                    "System not ready, putting on hold: " + app);
3617            checkTime(startTime, "startProcess: returning with proc on hold");
3618            return app;
3619        }
3620
3621        checkTime(startTime, "startProcess: stepping in to startProcess");
3622        startProcessLocked(
3623                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3624        checkTime(startTime, "startProcess: done starting proc!");
3625        return (app.pid != 0) ? app : null;
3626    }
3627
3628    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3629        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3630    }
3631
3632    private final void startProcessLocked(ProcessRecord app,
3633            String hostingType, String hostingNameStr) {
3634        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3635                null /* entryPoint */, null /* entryPointArgs */);
3636    }
3637
3638    private final void startProcessLocked(ProcessRecord app, String hostingType,
3639            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3640        long startTime = SystemClock.elapsedRealtime();
3641        if (app.pid > 0 && app.pid != MY_PID) {
3642            checkTime(startTime, "startProcess: removing from pids map");
3643            synchronized (mPidsSelfLocked) {
3644                mPidsSelfLocked.remove(app.pid);
3645                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3646            }
3647            checkTime(startTime, "startProcess: done removing from pids map");
3648            app.setPid(0);
3649        }
3650
3651        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3652                "startProcessLocked removing on hold: " + app);
3653        mProcessesOnHold.remove(app);
3654
3655        checkTime(startTime, "startProcess: starting to update cpu stats");
3656        updateCpuStats();
3657        checkTime(startTime, "startProcess: done updating cpu stats");
3658
3659        try {
3660            try {
3661                final int userId = UserHandle.getUserId(app.uid);
3662                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3663            } catch (RemoteException e) {
3664                throw e.rethrowAsRuntimeException();
3665            }
3666
3667            int uid = app.uid;
3668            int[] gids = null;
3669            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3670            if (!app.isolated) {
3671                int[] permGids = null;
3672                try {
3673                    checkTime(startTime, "startProcess: getting gids from package manager");
3674                    final IPackageManager pm = AppGlobals.getPackageManager();
3675                    permGids = pm.getPackageGids(app.info.packageName,
3676                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3677                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3678                            MountServiceInternal.class);
3679                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3680                            app.info.packageName);
3681                } catch (RemoteException e) {
3682                    throw e.rethrowAsRuntimeException();
3683                }
3684
3685                /*
3686                 * Add shared application and profile GIDs so applications can share some
3687                 * resources like shared libraries and access user-wide resources
3688                 */
3689                if (ArrayUtils.isEmpty(permGids)) {
3690                    gids = new int[2];
3691                } else {
3692                    gids = new int[permGids.length + 2];
3693                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3694                }
3695                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3696                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3697            }
3698            checkTime(startTime, "startProcess: building args");
3699            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3700                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3701                        && mTopComponent != null
3702                        && app.processName.equals(mTopComponent.getPackageName())) {
3703                    uid = 0;
3704                }
3705                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3706                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3707                    uid = 0;
3708                }
3709            }
3710            int debugFlags = 0;
3711            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3712                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3713                // Also turn on CheckJNI for debuggable apps. It's quite
3714                // awkward to turn on otherwise.
3715                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3716            }
3717            // Run the app in safe mode if its manifest requests so or the
3718            // system is booted in safe mode.
3719            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3720                mSafeMode == true) {
3721                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3722            }
3723            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3724                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3725            }
3726            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3727            if ("true".equals(genDebugInfoProperty)) {
3728                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3729            }
3730            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3731                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3732            }
3733            if ("1".equals(SystemProperties.get("debug.assert"))) {
3734                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3735            }
3736            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3737                // Enable all debug flags required by the native debugger.
3738                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3739                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3740                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3741                mNativeDebuggingApp = null;
3742            }
3743
3744            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3745            if (requiredAbi == null) {
3746                requiredAbi = Build.SUPPORTED_ABIS[0];
3747            }
3748
3749            String instructionSet = null;
3750            if (app.info.primaryCpuAbi != null) {
3751                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3752            }
3753
3754            app.gids = gids;
3755            app.requiredAbi = requiredAbi;
3756            app.instructionSet = instructionSet;
3757
3758            // Start the process.  It will either succeed and return a result containing
3759            // the PID of the new process, or else throw a RuntimeException.
3760            boolean isActivityProcess = (entryPoint == null);
3761            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3762            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3763                    app.processName);
3764            checkTime(startTime, "startProcess: asking zygote to start proc");
3765            Process.ProcessStartResult startResult = Process.start(entryPoint,
3766                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3767                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3768                    app.info.dataDir, entryPointArgs);
3769            checkTime(startTime, "startProcess: returned from zygote!");
3770            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3771
3772            if (app.isolated) {
3773                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3774            }
3775            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3776            checkTime(startTime, "startProcess: done updating battery stats");
3777
3778            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3779                    UserHandle.getUserId(uid), startResult.pid, uid,
3780                    app.processName, hostingType,
3781                    hostingNameStr != null ? hostingNameStr : "");
3782
3783            try {
3784                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3785                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3786            } catch (RemoteException ex) {
3787                // Ignore
3788            }
3789
3790            if (app.persistent) {
3791                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3792            }
3793
3794            checkTime(startTime, "startProcess: building log message");
3795            StringBuilder buf = mStringBuilder;
3796            buf.setLength(0);
3797            buf.append("Start proc ");
3798            buf.append(startResult.pid);
3799            buf.append(':');
3800            buf.append(app.processName);
3801            buf.append('/');
3802            UserHandle.formatUid(buf, uid);
3803            if (!isActivityProcess) {
3804                buf.append(" [");
3805                buf.append(entryPoint);
3806                buf.append("]");
3807            }
3808            buf.append(" for ");
3809            buf.append(hostingType);
3810            if (hostingNameStr != null) {
3811                buf.append(" ");
3812                buf.append(hostingNameStr);
3813            }
3814            Slog.i(TAG, buf.toString());
3815            app.setPid(startResult.pid);
3816            app.usingWrapper = startResult.usingWrapper;
3817            app.removed = false;
3818            app.killed = false;
3819            app.killedByAm = false;
3820            checkTime(startTime, "startProcess: starting to update pids map");
3821            synchronized (mPidsSelfLocked) {
3822                this.mPidsSelfLocked.put(startResult.pid, app);
3823                if (isActivityProcess) {
3824                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3825                    msg.obj = app;
3826                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3827                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3828                }
3829            }
3830            checkTime(startTime, "startProcess: done updating pids map");
3831        } catch (RuntimeException e) {
3832            Slog.e(TAG, "Failure starting process " + app.processName, e);
3833
3834            // Something went very wrong while trying to start this process; one
3835            // common case is when the package is frozen due to an active
3836            // upgrade. To recover, clean up any active bookkeeping related to
3837            // starting this process. (We already invoked this method once when
3838            // the package was initially frozen through KILL_APPLICATION_MSG, so
3839            // it doesn't hurt to use it again.)
3840            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3841                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3842        }
3843    }
3844
3845    void updateUsageStats(ActivityRecord component, boolean resumed) {
3846        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3847                "updateUsageStats: comp=" + component + "res=" + resumed);
3848        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3849        if (resumed) {
3850            if (mUsageStatsService != null) {
3851                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3852                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3853            }
3854            synchronized (stats) {
3855                stats.noteActivityResumedLocked(component.app.uid);
3856            }
3857        } else {
3858            if (mUsageStatsService != null) {
3859                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3860                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3861            }
3862            synchronized (stats) {
3863                stats.noteActivityPausedLocked(component.app.uid);
3864            }
3865        }
3866    }
3867
3868    Intent getHomeIntent() {
3869        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3870        intent.setComponent(mTopComponent);
3871        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3872        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3873            intent.addCategory(Intent.CATEGORY_HOME);
3874        }
3875        return intent;
3876    }
3877
3878    boolean startHomeActivityLocked(int userId, String reason) {
3879        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3880                && mTopAction == null) {
3881            // We are running in factory test mode, but unable to find
3882            // the factory test app, so just sit around displaying the
3883            // error message and don't try to start anything.
3884            return false;
3885        }
3886        Intent intent = getHomeIntent();
3887        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3888        if (aInfo != null) {
3889            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3890            // Don't do this if the home app is currently being
3891            // instrumented.
3892            aInfo = new ActivityInfo(aInfo);
3893            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3894            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3895                    aInfo.applicationInfo.uid, true);
3896            if (app == null || app.instrumentationClass == null) {
3897                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3898                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3899            }
3900        } else {
3901            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3902        }
3903
3904        return true;
3905    }
3906
3907    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3908        ActivityInfo ai = null;
3909        ComponentName comp = intent.getComponent();
3910        try {
3911            if (comp != null) {
3912                // Factory test.
3913                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3914            } else {
3915                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3916                        intent,
3917                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3918                        flags, userId);
3919
3920                if (info != null) {
3921                    ai = info.activityInfo;
3922                }
3923            }
3924        } catch (RemoteException e) {
3925            // ignore
3926        }
3927
3928        return ai;
3929    }
3930
3931    /**
3932     * Starts the "new version setup screen" if appropriate.
3933     */
3934    void startSetupActivityLocked() {
3935        // Only do this once per boot.
3936        if (mCheckedForSetup) {
3937            return;
3938        }
3939
3940        // We will show this screen if the current one is a different
3941        // version than the last one shown, and we are not running in
3942        // low-level factory test mode.
3943        final ContentResolver resolver = mContext.getContentResolver();
3944        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3945                Settings.Global.getInt(resolver,
3946                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3947            mCheckedForSetup = true;
3948
3949            // See if we should be showing the platform update setup UI.
3950            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3951            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3952                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3953            if (!ris.isEmpty()) {
3954                final ResolveInfo ri = ris.get(0);
3955                String vers = ri.activityInfo.metaData != null
3956                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3957                        : null;
3958                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3959                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3960                            Intent.METADATA_SETUP_VERSION);
3961                }
3962                String lastVers = Settings.Secure.getString(
3963                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3964                if (vers != null && !vers.equals(lastVers)) {
3965                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3966                    intent.setComponent(new ComponentName(
3967                            ri.activityInfo.packageName, ri.activityInfo.name));
3968                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3969                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3970                            null, 0, 0, 0, null, false, false, null, null, null);
3971                }
3972            }
3973        }
3974    }
3975
3976    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3977        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3978    }
3979
3980    void enforceNotIsolatedCaller(String caller) {
3981        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3982            throw new SecurityException("Isolated process not allowed to call " + caller);
3983        }
3984    }
3985
3986    void enforceShellRestriction(String restriction, int userHandle) {
3987        if (Binder.getCallingUid() == Process.SHELL_UID) {
3988            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3989                throw new SecurityException("Shell does not have permission to access user "
3990                        + userHandle);
3991            }
3992        }
3993    }
3994
3995    @Override
3996    public int getFrontActivityScreenCompatMode() {
3997        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3998        synchronized (this) {
3999            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4000        }
4001    }
4002
4003    @Override
4004    public void setFrontActivityScreenCompatMode(int mode) {
4005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4006                "setFrontActivityScreenCompatMode");
4007        synchronized (this) {
4008            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4009        }
4010    }
4011
4012    @Override
4013    public int getPackageScreenCompatMode(String packageName) {
4014        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4015        synchronized (this) {
4016            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4017        }
4018    }
4019
4020    @Override
4021    public void setPackageScreenCompatMode(String packageName, int mode) {
4022        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4023                "setPackageScreenCompatMode");
4024        synchronized (this) {
4025            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4026        }
4027    }
4028
4029    @Override
4030    public boolean getPackageAskScreenCompat(String packageName) {
4031        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4032        synchronized (this) {
4033            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4034        }
4035    }
4036
4037    @Override
4038    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4039        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4040                "setPackageAskScreenCompat");
4041        synchronized (this) {
4042            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4043        }
4044    }
4045
4046    private boolean hasUsageStatsPermission(String callingPackage) {
4047        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4048                Binder.getCallingUid(), callingPackage);
4049        if (mode == AppOpsManager.MODE_DEFAULT) {
4050            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4051                    == PackageManager.PERMISSION_GRANTED;
4052        }
4053        return mode == AppOpsManager.MODE_ALLOWED;
4054    }
4055
4056    @Override
4057    public int getPackageProcessState(String packageName, String callingPackage) {
4058        if (!hasUsageStatsPermission(callingPackage)) {
4059            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4060                    "getPackageProcessState");
4061        }
4062
4063        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4064        synchronized (this) {
4065            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4066                final ProcessRecord proc = mLruProcesses.get(i);
4067                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4068                        || procState > proc.setProcState) {
4069                    boolean found = false;
4070                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4071                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4072                            procState = proc.setProcState;
4073                            found = true;
4074                        }
4075                    }
4076                    if (proc.pkgDeps != null && !found) {
4077                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4078                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4079                                procState = proc.setProcState;
4080                                break;
4081                            }
4082                        }
4083                    }
4084                }
4085            }
4086        }
4087        return procState;
4088    }
4089
4090    @Override
4091    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4092        synchronized (this) {
4093            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4094            if (app == null) {
4095                return false;
4096            }
4097            if (app.trimMemoryLevel < level && app.thread != null &&
4098                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4099                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4100                try {
4101                    app.thread.scheduleTrimMemory(level);
4102                    app.trimMemoryLevel = level;
4103                    return true;
4104                } catch (RemoteException e) {
4105                    // Fallthrough to failure case.
4106                }
4107            }
4108        }
4109        return false;
4110    }
4111
4112    private void dispatchProcessesChanged() {
4113        int N;
4114        synchronized (this) {
4115            N = mPendingProcessChanges.size();
4116            if (mActiveProcessChanges.length < N) {
4117                mActiveProcessChanges = new ProcessChangeItem[N];
4118            }
4119            mPendingProcessChanges.toArray(mActiveProcessChanges);
4120            mPendingProcessChanges.clear();
4121            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4122                    "*** Delivering " + N + " process changes");
4123        }
4124
4125        int i = mProcessObservers.beginBroadcast();
4126        while (i > 0) {
4127            i--;
4128            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4129            if (observer != null) {
4130                try {
4131                    for (int j=0; j<N; j++) {
4132                        ProcessChangeItem item = mActiveProcessChanges[j];
4133                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4134                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4135                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4136                                    + item.uid + ": " + item.foregroundActivities);
4137                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4138                                    item.foregroundActivities);
4139                        }
4140                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4141                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4142                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4143                                    + ": " + item.processState);
4144                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4145                        }
4146                    }
4147                } catch (RemoteException e) {
4148                }
4149            }
4150        }
4151        mProcessObservers.finishBroadcast();
4152
4153        synchronized (this) {
4154            for (int j=0; j<N; j++) {
4155                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4156            }
4157        }
4158    }
4159
4160    private void dispatchProcessDied(int pid, int uid) {
4161        int i = mProcessObservers.beginBroadcast();
4162        while (i > 0) {
4163            i--;
4164            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4165            if (observer != null) {
4166                try {
4167                    observer.onProcessDied(pid, uid);
4168                } catch (RemoteException e) {
4169                }
4170            }
4171        }
4172        mProcessObservers.finishBroadcast();
4173    }
4174
4175    private void dispatchUidsChanged() {
4176        int N;
4177        synchronized (this) {
4178            N = mPendingUidChanges.size();
4179            if (mActiveUidChanges.length < N) {
4180                mActiveUidChanges = new UidRecord.ChangeItem[N];
4181            }
4182            for (int i=0; i<N; i++) {
4183                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4184                mActiveUidChanges[i] = change;
4185                if (change.uidRecord != null) {
4186                    change.uidRecord.pendingChange = null;
4187                    change.uidRecord = null;
4188                }
4189            }
4190            mPendingUidChanges.clear();
4191            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4192                    "*** Delivering " + N + " uid changes");
4193        }
4194
4195        if (mLocalPowerManager != null) {
4196            for (int j=0; j<N; j++) {
4197                UidRecord.ChangeItem item = mActiveUidChanges[j];
4198                if (item.change == UidRecord.CHANGE_GONE
4199                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4200                    mLocalPowerManager.uidGone(item.uid);
4201                } else {
4202                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4203                }
4204            }
4205        }
4206
4207        int i = mUidObservers.beginBroadcast();
4208        while (i > 0) {
4209            i--;
4210            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4211            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4212            if (observer != null) {
4213                try {
4214                    for (int j=0; j<N; j++) {
4215                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4216                        final int change = item.change;
4217                        UidRecord validateUid = null;
4218                        if (VALIDATE_UID_STATES && i == 0) {
4219                            validateUid = mValidateUids.get(item.uid);
4220                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4221                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4222                                validateUid = new UidRecord(item.uid);
4223                                mValidateUids.put(item.uid, validateUid);
4224                            }
4225                        }
4226                        if (change == UidRecord.CHANGE_IDLE
4227                                || change == UidRecord.CHANGE_GONE_IDLE) {
4228                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4229                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4230                                        "UID idle uid=" + item.uid);
4231                                observer.onUidIdle(item.uid);
4232                            }
4233                            if (VALIDATE_UID_STATES && i == 0) {
4234                                if (validateUid != null) {
4235                                    validateUid.idle = true;
4236                                }
4237                            }
4238                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4239                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4240                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4241                                        "UID active uid=" + item.uid);
4242                                observer.onUidActive(item.uid);
4243                            }
4244                            if (VALIDATE_UID_STATES && i == 0) {
4245                                validateUid.idle = false;
4246                            }
4247                        }
4248                        if (change == UidRecord.CHANGE_GONE
4249                                || change == UidRecord.CHANGE_GONE_IDLE) {
4250                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4251                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4252                                        "UID gone uid=" + item.uid);
4253                                observer.onUidGone(item.uid);
4254                            }
4255                            if (VALIDATE_UID_STATES && i == 0) {
4256                                if (validateUid != null) {
4257                                    mValidateUids.remove(item.uid);
4258                                }
4259                            }
4260                        } else {
4261                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4262                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4263                                        "UID CHANGED uid=" + item.uid
4264                                                + ": " + item.processState);
4265                                observer.onUidStateChanged(item.uid, item.processState);
4266                            }
4267                            if (VALIDATE_UID_STATES && i == 0) {
4268                                validateUid.curProcState = validateUid.setProcState
4269                                        = item.processState;
4270                            }
4271                        }
4272                    }
4273                } catch (RemoteException e) {
4274                }
4275            }
4276        }
4277        mUidObservers.finishBroadcast();
4278
4279        synchronized (this) {
4280            for (int j=0; j<N; j++) {
4281                mAvailUidChanges.add(mActiveUidChanges[j]);
4282            }
4283        }
4284    }
4285
4286    @Override
4287    public final int startActivity(IApplicationThread caller, String callingPackage,
4288            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4289            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4290        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4291                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4292                UserHandle.getCallingUserId());
4293    }
4294
4295    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4296        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4297        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4298                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4299                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4300
4301        // TODO: Switch to user app stacks here.
4302        String mimeType = intent.getType();
4303        final Uri data = intent.getData();
4304        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4305            mimeType = getProviderMimeType(data, userId);
4306        }
4307        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4308
4309        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4310        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4311                null, 0, 0, null, null, null, null, false, userId, container, null);
4312    }
4313
4314    @Override
4315    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4316            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4317            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4318        enforceNotIsolatedCaller("startActivity");
4319        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4320                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4321        // TODO: Switch to user app stacks here.
4322        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4323                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4324                profilerInfo, null, null, bOptions, false, userId, null, null);
4325    }
4326
4327    @Override
4328    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4329            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4330            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4331            int userId) {
4332
4333        // This is very dangerous -- it allows you to perform a start activity (including
4334        // permission grants) as any app that may launch one of your own activities.  So
4335        // we will only allow this to be done from activities that are part of the core framework,
4336        // and then only when they are running as the system.
4337        final ActivityRecord sourceRecord;
4338        final int targetUid;
4339        final String targetPackage;
4340        synchronized (this) {
4341            if (resultTo == null) {
4342                throw new SecurityException("Must be called from an activity");
4343            }
4344            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4345            if (sourceRecord == null) {
4346                throw new SecurityException("Called with bad activity token: " + resultTo);
4347            }
4348            if (!sourceRecord.info.packageName.equals("android")) {
4349                throw new SecurityException(
4350                        "Must be called from an activity that is declared in the android package");
4351            }
4352            if (sourceRecord.app == null) {
4353                throw new SecurityException("Called without a process attached to activity");
4354            }
4355            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4356                // This is still okay, as long as this activity is running under the
4357                // uid of the original calling activity.
4358                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4359                    throw new SecurityException(
4360                            "Calling activity in uid " + sourceRecord.app.uid
4361                                    + " must be system uid or original calling uid "
4362                                    + sourceRecord.launchedFromUid);
4363                }
4364            }
4365            if (ignoreTargetSecurity) {
4366                if (intent.getComponent() == null) {
4367                    throw new SecurityException(
4368                            "Component must be specified with ignoreTargetSecurity");
4369                }
4370                if (intent.getSelector() != null) {
4371                    throw new SecurityException(
4372                            "Selector not allowed with ignoreTargetSecurity");
4373                }
4374            }
4375            targetUid = sourceRecord.launchedFromUid;
4376            targetPackage = sourceRecord.launchedFromPackage;
4377        }
4378
4379        if (userId == UserHandle.USER_NULL) {
4380            userId = UserHandle.getUserId(sourceRecord.app.uid);
4381        }
4382
4383        // TODO: Switch to user app stacks here.
4384        try {
4385            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4386                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4387                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4388            return ret;
4389        } catch (SecurityException e) {
4390            // XXX need to figure out how to propagate to original app.
4391            // A SecurityException here is generally actually a fault of the original
4392            // calling activity (such as a fairly granting permissions), so propagate it
4393            // back to them.
4394            /*
4395            StringBuilder msg = new StringBuilder();
4396            msg.append("While launching");
4397            msg.append(intent.toString());
4398            msg.append(": ");
4399            msg.append(e.getMessage());
4400            */
4401            throw e;
4402        }
4403    }
4404
4405    @Override
4406    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4407            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4408            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4409        enforceNotIsolatedCaller("startActivityAndWait");
4410        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4411                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4412        WaitResult res = new WaitResult();
4413        // TODO: Switch to user app stacks here.
4414        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4415                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4416                bOptions, false, userId, null, null);
4417        return res;
4418    }
4419
4420    @Override
4421    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4422            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4423            int startFlags, Configuration config, Bundle bOptions, int userId) {
4424        enforceNotIsolatedCaller("startActivityWithConfig");
4425        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4426                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4427        // TODO: Switch to user app stacks here.
4428        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4429                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4430                null, null, config, bOptions, false, userId, null, null);
4431        return ret;
4432    }
4433
4434    @Override
4435    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4436            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4437            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4438            throws TransactionTooLargeException {
4439        enforceNotIsolatedCaller("startActivityIntentSender");
4440        // Refuse possible leaked file descriptors
4441        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4442            throw new IllegalArgumentException("File descriptors passed in Intent");
4443        }
4444
4445        IIntentSender sender = intent.getTarget();
4446        if (!(sender instanceof PendingIntentRecord)) {
4447            throw new IllegalArgumentException("Bad PendingIntent object");
4448        }
4449
4450        PendingIntentRecord pir = (PendingIntentRecord)sender;
4451
4452        synchronized (this) {
4453            // If this is coming from the currently resumed activity, it is
4454            // effectively saying that app switches are allowed at this point.
4455            final ActivityStack stack = getFocusedStack();
4456            if (stack.mResumedActivity != null &&
4457                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4458                mAppSwitchesAllowedTime = 0;
4459            }
4460        }
4461        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4462                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4463        return ret;
4464    }
4465
4466    @Override
4467    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4468            Intent intent, String resolvedType, IVoiceInteractionSession session,
4469            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4470            Bundle bOptions, int userId) {
4471        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4472                != PackageManager.PERMISSION_GRANTED) {
4473            String msg = "Permission Denial: startVoiceActivity() from pid="
4474                    + Binder.getCallingPid()
4475                    + ", uid=" + Binder.getCallingUid()
4476                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4477            Slog.w(TAG, msg);
4478            throw new SecurityException(msg);
4479        }
4480        if (session == null || interactor == null) {
4481            throw new NullPointerException("null session or interactor");
4482        }
4483        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4484                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4485        // TODO: Switch to user app stacks here.
4486        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4487                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4488                null, bOptions, false, userId, null, null);
4489    }
4490
4491    @Override
4492    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4493            throws RemoteException {
4494        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4495        synchronized (this) {
4496            ActivityRecord activity = getFocusedStack().topActivity();
4497            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4498                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4499            }
4500            if (mRunningVoice != null || activity.task.voiceSession != null
4501                    || activity.voiceSession != null) {
4502                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4503                return;
4504            }
4505            if (activity.pendingVoiceInteractionStart) {
4506                Slog.w(TAG, "Pending start of voice interaction already.");
4507                return;
4508            }
4509            activity.pendingVoiceInteractionStart = true;
4510        }
4511        LocalServices.getService(VoiceInteractionManagerInternal.class)
4512                .startLocalVoiceInteraction(callingActivity, options);
4513    }
4514
4515    @Override
4516    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4517        LocalServices.getService(VoiceInteractionManagerInternal.class)
4518                .stopLocalVoiceInteraction(callingActivity);
4519    }
4520
4521    @Override
4522    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4523        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4524                .supportsLocalVoiceInteraction();
4525    }
4526
4527    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4528            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4529        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4530        if (activityToCallback == null) return;
4531        activityToCallback.setVoiceSessionLocked(voiceSession);
4532
4533        // Inform the activity
4534        try {
4535            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4536                    voiceInteractor);
4537            long token = Binder.clearCallingIdentity();
4538            try {
4539                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4540            } finally {
4541                Binder.restoreCallingIdentity(token);
4542            }
4543            // TODO: VI Should we cache the activity so that it's easier to find later
4544            // rather than scan through all the stacks and activities?
4545        } catch (RemoteException re) {
4546            activityToCallback.clearVoiceSessionLocked();
4547            // TODO: VI Should this terminate the voice session?
4548        }
4549    }
4550
4551    @Override
4552    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4553        synchronized (this) {
4554            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4555                if (keepAwake) {
4556                    mVoiceWakeLock.acquire();
4557                } else {
4558                    mVoiceWakeLock.release();
4559                }
4560            }
4561        }
4562    }
4563
4564    @Override
4565    public boolean startNextMatchingActivity(IBinder callingActivity,
4566            Intent intent, Bundle bOptions) {
4567        // Refuse possible leaked file descriptors
4568        if (intent != null && intent.hasFileDescriptors() == true) {
4569            throw new IllegalArgumentException("File descriptors passed in Intent");
4570        }
4571        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4572
4573        synchronized (this) {
4574            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4575            if (r == null) {
4576                ActivityOptions.abort(options);
4577                return false;
4578            }
4579            if (r.app == null || r.app.thread == null) {
4580                // The caller is not running...  d'oh!
4581                ActivityOptions.abort(options);
4582                return false;
4583            }
4584            intent = new Intent(intent);
4585            // The caller is not allowed to change the data.
4586            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4587            // And we are resetting to find the next component...
4588            intent.setComponent(null);
4589
4590            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4591
4592            ActivityInfo aInfo = null;
4593            try {
4594                List<ResolveInfo> resolves =
4595                    AppGlobals.getPackageManager().queryIntentActivities(
4596                            intent, r.resolvedType,
4597                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4598                            UserHandle.getCallingUserId()).getList();
4599
4600                // Look for the original activity in the list...
4601                final int N = resolves != null ? resolves.size() : 0;
4602                for (int i=0; i<N; i++) {
4603                    ResolveInfo rInfo = resolves.get(i);
4604                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4605                            && rInfo.activityInfo.name.equals(r.info.name)) {
4606                        // We found the current one...  the next matching is
4607                        // after it.
4608                        i++;
4609                        if (i<N) {
4610                            aInfo = resolves.get(i).activityInfo;
4611                        }
4612                        if (debug) {
4613                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4614                                    + "/" + r.info.name);
4615                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4616                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4617                        }
4618                        break;
4619                    }
4620                }
4621            } catch (RemoteException e) {
4622            }
4623
4624            if (aInfo == null) {
4625                // Nobody who is next!
4626                ActivityOptions.abort(options);
4627                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4628                return false;
4629            }
4630
4631            intent.setComponent(new ComponentName(
4632                    aInfo.applicationInfo.packageName, aInfo.name));
4633            intent.setFlags(intent.getFlags()&~(
4634                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4635                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4636                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4637                    Intent.FLAG_ACTIVITY_NEW_TASK));
4638
4639            // Okay now we need to start the new activity, replacing the
4640            // currently running activity.  This is a little tricky because
4641            // we want to start the new one as if the current one is finished,
4642            // but not finish the current one first so that there is no flicker.
4643            // And thus...
4644            final boolean wasFinishing = r.finishing;
4645            r.finishing = true;
4646
4647            // Propagate reply information over to the new activity.
4648            final ActivityRecord resultTo = r.resultTo;
4649            final String resultWho = r.resultWho;
4650            final int requestCode = r.requestCode;
4651            r.resultTo = null;
4652            if (resultTo != null) {
4653                resultTo.removeResultsLocked(r, resultWho, requestCode);
4654            }
4655
4656            final long origId = Binder.clearCallingIdentity();
4657            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4658                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4659                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4660                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4661                    false, false, null, null, null);
4662            Binder.restoreCallingIdentity(origId);
4663
4664            r.finishing = wasFinishing;
4665            if (res != ActivityManager.START_SUCCESS) {
4666                return false;
4667            }
4668            return true;
4669        }
4670    }
4671
4672    @Override
4673    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4674        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4675            String msg = "Permission Denial: startActivityFromRecents called without " +
4676                    START_TASKS_FROM_RECENTS;
4677            Slog.w(TAG, msg);
4678            throw new SecurityException(msg);
4679        }
4680        final long origId = Binder.clearCallingIdentity();
4681        try {
4682            synchronized (this) {
4683                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4684            }
4685        } finally {
4686            Binder.restoreCallingIdentity(origId);
4687        }
4688    }
4689
4690    final int startActivityInPackage(int uid, String callingPackage,
4691            Intent intent, String resolvedType, IBinder resultTo,
4692            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4693            IActivityContainer container, TaskRecord inTask) {
4694
4695        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4696                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4697
4698        // TODO: Switch to user app stacks here.
4699        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4700                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4701                null, null, null, bOptions, false, userId, container, inTask);
4702        return ret;
4703    }
4704
4705    @Override
4706    public final int startActivities(IApplicationThread caller, String callingPackage,
4707            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4708            int userId) {
4709        enforceNotIsolatedCaller("startActivities");
4710        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4711                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4712        // TODO: Switch to user app stacks here.
4713        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4714                resolvedTypes, resultTo, bOptions, userId);
4715        return ret;
4716    }
4717
4718    final int startActivitiesInPackage(int uid, String callingPackage,
4719            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4720            Bundle bOptions, int userId) {
4721
4722        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4723                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4724        // TODO: Switch to user app stacks here.
4725        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4726                resultTo, bOptions, userId);
4727        return ret;
4728    }
4729
4730    @Override
4731    public void reportActivityFullyDrawn(IBinder token) {
4732        synchronized (this) {
4733            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4734            if (r == null) {
4735                return;
4736            }
4737            r.reportFullyDrawnLocked();
4738        }
4739    }
4740
4741    @Override
4742    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4743        synchronized (this) {
4744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4745            if (r == null) {
4746                return;
4747            }
4748            TaskRecord task = r.task;
4749            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4750                // Fixed screen orientation isn't supported when activities aren't in full screen
4751                // mode.
4752                return;
4753            }
4754            final long origId = Binder.clearCallingIdentity();
4755            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4756            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4757                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4758            if (config != null) {
4759                r.frozenBeforeDestroy = true;
4760                if (!updateConfigurationLocked(config, r, false)) {
4761                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4762                }
4763            }
4764            Binder.restoreCallingIdentity(origId);
4765        }
4766    }
4767
4768    @Override
4769    public int getRequestedOrientation(IBinder token) {
4770        synchronized (this) {
4771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4772            if (r == null) {
4773                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4774            }
4775            return mWindowManager.getAppOrientation(r.appToken);
4776        }
4777    }
4778
4779    /**
4780     * This is the internal entry point for handling Activity.finish().
4781     *
4782     * @param token The Binder token referencing the Activity we want to finish.
4783     * @param resultCode Result code, if any, from this Activity.
4784     * @param resultData Result data (Intent), if any, from this Activity.
4785     * @param finishTask Whether to finish the task associated with this Activity.
4786     *
4787     * @return Returns true if the activity successfully finished, or false if it is still running.
4788     */
4789    @Override
4790    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4791            int finishTask) {
4792        // Refuse possible leaked file descriptors
4793        if (resultData != null && resultData.hasFileDescriptors() == true) {
4794            throw new IllegalArgumentException("File descriptors passed in Intent");
4795        }
4796
4797        synchronized(this) {
4798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4799            if (r == null) {
4800                return true;
4801            }
4802            // Keep track of the root activity of the task before we finish it
4803            TaskRecord tr = r.task;
4804            ActivityRecord rootR = tr.getRootActivity();
4805            if (rootR == null) {
4806                Slog.w(TAG, "Finishing task with all activities already finished");
4807            }
4808            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4809            // finish.
4810            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4811                    mStackSupervisor.isLastLockedTask(tr)) {
4812                Slog.i(TAG, "Not finishing task in lock task mode");
4813                mStackSupervisor.showLockTaskToast();
4814                return false;
4815            }
4816            if (mController != null) {
4817                // Find the first activity that is not finishing.
4818                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4819                if (next != null) {
4820                    // ask watcher if this is allowed
4821                    boolean resumeOK = true;
4822                    try {
4823                        resumeOK = mController.activityResuming(next.packageName);
4824                    } catch (RemoteException e) {
4825                        mController = null;
4826                        Watchdog.getInstance().setActivityController(null);
4827                    }
4828
4829                    if (!resumeOK) {
4830                        Slog.i(TAG, "Not finishing activity because controller resumed");
4831                        return false;
4832                    }
4833                }
4834            }
4835            final long origId = Binder.clearCallingIdentity();
4836            try {
4837                boolean res;
4838                final boolean finishWithRootActivity =
4839                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4840                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4841                        || (finishWithRootActivity && r == rootR)) {
4842                    // If requested, remove the task that is associated to this activity only if it
4843                    // was the root activity in the task. The result code and data is ignored
4844                    // because we don't support returning them across task boundaries. Also, to
4845                    // keep backwards compatibility we remove the task from recents when finishing
4846                    // task with root activity.
4847                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4848                    if (!res) {
4849                        Slog.i(TAG, "Removing task failed to finish activity");
4850                    }
4851                } else {
4852                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4853                            resultData, "app-request", true);
4854                    if (!res) {
4855                        Slog.i(TAG, "Failed to finish by app-request");
4856                    }
4857                }
4858                return res;
4859            } finally {
4860                Binder.restoreCallingIdentity(origId);
4861            }
4862        }
4863    }
4864
4865    @Override
4866    public final void finishHeavyWeightApp() {
4867        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4868                != PackageManager.PERMISSION_GRANTED) {
4869            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4870                    + Binder.getCallingPid()
4871                    + ", uid=" + Binder.getCallingUid()
4872                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4873            Slog.w(TAG, msg);
4874            throw new SecurityException(msg);
4875        }
4876
4877        synchronized(this) {
4878            if (mHeavyWeightProcess == null) {
4879                return;
4880            }
4881
4882            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4883            for (int i = 0; i < activities.size(); i++) {
4884                ActivityRecord r = activities.get(i);
4885                if (!r.finishing && r.isInStackLocked()) {
4886                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4887                            null, "finish-heavy", true);
4888                }
4889            }
4890
4891            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4892                    mHeavyWeightProcess.userId, 0));
4893            mHeavyWeightProcess = null;
4894        }
4895    }
4896
4897    @Override
4898    public void crashApplication(int uid, int initialPid, String packageName,
4899            String message) {
4900        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4901                != PackageManager.PERMISSION_GRANTED) {
4902            String msg = "Permission Denial: crashApplication() from pid="
4903                    + Binder.getCallingPid()
4904                    + ", uid=" + Binder.getCallingUid()
4905                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4906            Slog.w(TAG, msg);
4907            throw new SecurityException(msg);
4908        }
4909
4910        synchronized(this) {
4911            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4912        }
4913    }
4914
4915    @Override
4916    public final void finishSubActivity(IBinder token, String resultWho,
4917            int requestCode) {
4918        synchronized(this) {
4919            final long origId = Binder.clearCallingIdentity();
4920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4921            if (r != null) {
4922                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4923            }
4924            Binder.restoreCallingIdentity(origId);
4925        }
4926    }
4927
4928    @Override
4929    public boolean finishActivityAffinity(IBinder token) {
4930        synchronized(this) {
4931            final long origId = Binder.clearCallingIdentity();
4932            try {
4933                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4934                if (r == null) {
4935                    return false;
4936                }
4937
4938                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4939                // can finish.
4940                final TaskRecord task = r.task;
4941                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4942                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4943                    mStackSupervisor.showLockTaskToast();
4944                    return false;
4945                }
4946                return task.stack.finishActivityAffinityLocked(r);
4947            } finally {
4948                Binder.restoreCallingIdentity(origId);
4949            }
4950        }
4951    }
4952
4953    @Override
4954    public void finishVoiceTask(IVoiceInteractionSession session) {
4955        synchronized (this) {
4956            final long origId = Binder.clearCallingIdentity();
4957            try {
4958                // TODO: VI Consider treating local voice interactions and voice tasks
4959                // differently here
4960                mStackSupervisor.finishVoiceTask(session);
4961            } finally {
4962                Binder.restoreCallingIdentity(origId);
4963            }
4964        }
4965
4966    }
4967
4968    @Override
4969    public boolean releaseActivityInstance(IBinder token) {
4970        synchronized(this) {
4971            final long origId = Binder.clearCallingIdentity();
4972            try {
4973                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4974                if (r == null) {
4975                    return false;
4976                }
4977                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4978            } finally {
4979                Binder.restoreCallingIdentity(origId);
4980            }
4981        }
4982    }
4983
4984    @Override
4985    public void releaseSomeActivities(IApplicationThread appInt) {
4986        synchronized(this) {
4987            final long origId = Binder.clearCallingIdentity();
4988            try {
4989                ProcessRecord app = getRecordForAppLocked(appInt);
4990                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4991            } finally {
4992                Binder.restoreCallingIdentity(origId);
4993            }
4994        }
4995    }
4996
4997    @Override
4998    public boolean willActivityBeVisible(IBinder token) {
4999        synchronized(this) {
5000            ActivityStack stack = ActivityRecord.getStackLocked(token);
5001            if (stack != null) {
5002                return stack.willActivityBeVisibleLocked(token);
5003            }
5004            return false;
5005        }
5006    }
5007
5008    @Override
5009    public void overridePendingTransition(IBinder token, String packageName,
5010            int enterAnim, int exitAnim) {
5011        synchronized(this) {
5012            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5013            if (self == null) {
5014                return;
5015            }
5016
5017            final long origId = Binder.clearCallingIdentity();
5018
5019            if (self.state == ActivityState.RESUMED
5020                    || self.state == ActivityState.PAUSING) {
5021                mWindowManager.overridePendingAppTransition(packageName,
5022                        enterAnim, exitAnim, null);
5023            }
5024
5025            Binder.restoreCallingIdentity(origId);
5026        }
5027    }
5028
5029    /**
5030     * Main function for removing an existing process from the activity manager
5031     * as a result of that process going away.  Clears out all connections
5032     * to the process.
5033     */
5034    private final void handleAppDiedLocked(ProcessRecord app,
5035            boolean restarting, boolean allowRestart) {
5036        int pid = app.pid;
5037        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5038        if (!kept && !restarting) {
5039            removeLruProcessLocked(app);
5040            if (pid > 0) {
5041                ProcessList.remove(pid);
5042            }
5043        }
5044
5045        if (mProfileProc == app) {
5046            clearProfilerLocked();
5047        }
5048
5049        // Remove this application's activities from active lists.
5050        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5051
5052        app.activities.clear();
5053
5054        if (app.instrumentationClass != null) {
5055            Slog.w(TAG, "Crash of app " + app.processName
5056                  + " running instrumentation " + app.instrumentationClass);
5057            Bundle info = new Bundle();
5058            info.putString("shortMsg", "Process crashed.");
5059            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5060        }
5061
5062        if (!restarting && hasVisibleActivities
5063                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5064            // If there was nothing to resume, and we are not already restarting this process, but
5065            // there is a visible activity that is hosted by the process...  then make sure all
5066            // visible activities are running, taking care of restarting this process.
5067            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5068        }
5069    }
5070
5071    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5072        IBinder threadBinder = thread.asBinder();
5073        // Find the application record.
5074        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5075            ProcessRecord rec = mLruProcesses.get(i);
5076            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5077                return i;
5078            }
5079        }
5080        return -1;
5081    }
5082
5083    final ProcessRecord getRecordForAppLocked(
5084            IApplicationThread thread) {
5085        if (thread == null) {
5086            return null;
5087        }
5088
5089        int appIndex = getLRURecordIndexForAppLocked(thread);
5090        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5091    }
5092
5093    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5094        // If there are no longer any background processes running,
5095        // and the app that died was not running instrumentation,
5096        // then tell everyone we are now low on memory.
5097        boolean haveBg = false;
5098        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5099            ProcessRecord rec = mLruProcesses.get(i);
5100            if (rec.thread != null
5101                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5102                haveBg = true;
5103                break;
5104            }
5105        }
5106
5107        if (!haveBg) {
5108            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5109            if (doReport) {
5110                long now = SystemClock.uptimeMillis();
5111                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5112                    doReport = false;
5113                } else {
5114                    mLastMemUsageReportTime = now;
5115                }
5116            }
5117            final ArrayList<ProcessMemInfo> memInfos
5118                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5119            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5120            long now = SystemClock.uptimeMillis();
5121            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5122                ProcessRecord rec = mLruProcesses.get(i);
5123                if (rec == dyingProc || rec.thread == null) {
5124                    continue;
5125                }
5126                if (doReport) {
5127                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5128                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5129                }
5130                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5131                    // The low memory report is overriding any current
5132                    // state for a GC request.  Make sure to do
5133                    // heavy/important/visible/foreground processes first.
5134                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5135                        rec.lastRequestedGc = 0;
5136                    } else {
5137                        rec.lastRequestedGc = rec.lastLowMemory;
5138                    }
5139                    rec.reportLowMemory = true;
5140                    rec.lastLowMemory = now;
5141                    mProcessesToGc.remove(rec);
5142                    addProcessToGcListLocked(rec);
5143                }
5144            }
5145            if (doReport) {
5146                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5147                mHandler.sendMessage(msg);
5148            }
5149            scheduleAppGcsLocked();
5150        }
5151    }
5152
5153    final void appDiedLocked(ProcessRecord app) {
5154       appDiedLocked(app, app.pid, app.thread, false);
5155    }
5156
5157    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5158            boolean fromBinderDied) {
5159        // First check if this ProcessRecord is actually active for the pid.
5160        synchronized (mPidsSelfLocked) {
5161            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5162            if (curProc != app) {
5163                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5164                return;
5165            }
5166        }
5167
5168        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5169        synchronized (stats) {
5170            stats.noteProcessDiedLocked(app.info.uid, pid);
5171        }
5172
5173        if (!app.killed) {
5174            if (!fromBinderDied) {
5175                Process.killProcessQuiet(pid);
5176            }
5177            killProcessGroup(app.uid, pid);
5178            app.killed = true;
5179        }
5180
5181        // Clean up already done if the process has been re-started.
5182        if (app.pid == pid && app.thread != null &&
5183                app.thread.asBinder() == thread.asBinder()) {
5184            boolean doLowMem = app.instrumentationClass == null;
5185            boolean doOomAdj = doLowMem;
5186            if (!app.killedByAm) {
5187                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5188                        + ") has died");
5189                mAllowLowerMemLevel = true;
5190            } else {
5191                // Note that we always want to do oom adj to update our state with the
5192                // new number of procs.
5193                mAllowLowerMemLevel = false;
5194                doLowMem = false;
5195            }
5196            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5197            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5198                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5199            handleAppDiedLocked(app, false, true);
5200
5201            if (doOomAdj) {
5202                updateOomAdjLocked();
5203            }
5204            if (doLowMem) {
5205                doLowMemReportIfNeededLocked(app);
5206            }
5207        } else if (app.pid != pid) {
5208            // A new process has already been started.
5209            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5210                    + ") has died and restarted (pid " + app.pid + ").");
5211            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5212        } else if (DEBUG_PROCESSES) {
5213            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5214                    + thread.asBinder());
5215        }
5216    }
5217
5218    /**
5219     * If a stack trace dump file is configured, dump process stack traces.
5220     * @param clearTraces causes the dump file to be erased prior to the new
5221     *    traces being written, if true; when false, the new traces will be
5222     *    appended to any existing file content.
5223     * @param firstPids of dalvik VM processes to dump stack traces for first
5224     * @param lastPids of dalvik VM processes to dump stack traces for last
5225     * @param nativeProcs optional list of native process names to dump stack crawls
5226     * @return file containing stack traces, or null if no dump file is configured
5227     */
5228    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5229            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5230        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5231        if (tracesPath == null || tracesPath.length() == 0) {
5232            return null;
5233        }
5234
5235        File tracesFile = new File(tracesPath);
5236        try {
5237            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5238            tracesFile.createNewFile();
5239            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5240        } catch (IOException e) {
5241            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5242            return null;
5243        }
5244
5245        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5246        return tracesFile;
5247    }
5248
5249    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5250            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5251        // Use a FileObserver to detect when traces finish writing.
5252        // The order of traces is considered important to maintain for legibility.
5253        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5254            @Override
5255            public synchronized void onEvent(int event, String path) { notify(); }
5256        };
5257
5258        try {
5259            observer.startWatching();
5260
5261            // First collect all of the stacks of the most important pids.
5262            if (firstPids != null) {
5263                try {
5264                    int num = firstPids.size();
5265                    for (int i = 0; i < num; i++) {
5266                        synchronized (observer) {
5267                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5268                                    + firstPids.get(i));
5269                            final long sime = SystemClock.elapsedRealtime();
5270                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5271                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5272                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5273                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5274                        }
5275                    }
5276                } catch (InterruptedException e) {
5277                    Slog.wtf(TAG, e);
5278                }
5279            }
5280
5281            // Next collect the stacks of the native pids
5282            if (nativeProcs != null) {
5283                int[] pids = Process.getPidsForCommands(nativeProcs);
5284                if (pids != null) {
5285                    for (int pid : pids) {
5286                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5287                        final long sime = SystemClock.elapsedRealtime();
5288                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5289                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5290                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5291                    }
5292                }
5293            }
5294
5295            // Lastly, measure CPU usage.
5296            if (processCpuTracker != null) {
5297                processCpuTracker.init();
5298                System.gc();
5299                processCpuTracker.update();
5300                try {
5301                    synchronized (processCpuTracker) {
5302                        processCpuTracker.wait(500); // measure over 1/2 second.
5303                    }
5304                } catch (InterruptedException e) {
5305                }
5306                processCpuTracker.update();
5307
5308                // We'll take the stack crawls of just the top apps using CPU.
5309                final int N = processCpuTracker.countWorkingStats();
5310                int numProcs = 0;
5311                for (int i=0; i<N && numProcs<5; i++) {
5312                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5313                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5314                        numProcs++;
5315                        try {
5316                            synchronized (observer) {
5317                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5318                                        + stats.pid);
5319                                final long stime = SystemClock.elapsedRealtime();
5320                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5321                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5322                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5323                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5324                            }
5325                        } catch (InterruptedException e) {
5326                            Slog.wtf(TAG, e);
5327                        }
5328                    } else if (DEBUG_ANR) {
5329                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5330                                + stats.pid);
5331                    }
5332                }
5333            }
5334        } finally {
5335            observer.stopWatching();
5336        }
5337    }
5338
5339    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5340        if (true || IS_USER_BUILD) {
5341            return;
5342        }
5343        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5344        if (tracesPath == null || tracesPath.length() == 0) {
5345            return;
5346        }
5347
5348        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5349        StrictMode.allowThreadDiskWrites();
5350        try {
5351            final File tracesFile = new File(tracesPath);
5352            final File tracesDir = tracesFile.getParentFile();
5353            final File tracesTmp = new File(tracesDir, "__tmp__");
5354            try {
5355                if (tracesFile.exists()) {
5356                    tracesTmp.delete();
5357                    tracesFile.renameTo(tracesTmp);
5358                }
5359                StringBuilder sb = new StringBuilder();
5360                Time tobj = new Time();
5361                tobj.set(System.currentTimeMillis());
5362                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5363                sb.append(": ");
5364                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5365                sb.append(" since ");
5366                sb.append(msg);
5367                FileOutputStream fos = new FileOutputStream(tracesFile);
5368                fos.write(sb.toString().getBytes());
5369                if (app == null) {
5370                    fos.write("\n*** No application process!".getBytes());
5371                }
5372                fos.close();
5373                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5374            } catch (IOException e) {
5375                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5376                return;
5377            }
5378
5379            if (app != null) {
5380                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5381                firstPids.add(app.pid);
5382                dumpStackTraces(tracesPath, firstPids, null, null, null);
5383            }
5384
5385            File lastTracesFile = null;
5386            File curTracesFile = null;
5387            for (int i=9; i>=0; i--) {
5388                String name = String.format(Locale.US, "slow%02d.txt", i);
5389                curTracesFile = new File(tracesDir, name);
5390                if (curTracesFile.exists()) {
5391                    if (lastTracesFile != null) {
5392                        curTracesFile.renameTo(lastTracesFile);
5393                    } else {
5394                        curTracesFile.delete();
5395                    }
5396                }
5397                lastTracesFile = curTracesFile;
5398            }
5399            tracesFile.renameTo(curTracesFile);
5400            if (tracesTmp.exists()) {
5401                tracesTmp.renameTo(tracesFile);
5402            }
5403        } finally {
5404            StrictMode.setThreadPolicy(oldPolicy);
5405        }
5406    }
5407
5408    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5409        if (!mLaunchWarningShown) {
5410            mLaunchWarningShown = true;
5411            mUiHandler.post(new Runnable() {
5412                @Override
5413                public void run() {
5414                    synchronized (ActivityManagerService.this) {
5415                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5416                        d.show();
5417                        mUiHandler.postDelayed(new Runnable() {
5418                            @Override
5419                            public void run() {
5420                                synchronized (ActivityManagerService.this) {
5421                                    d.dismiss();
5422                                    mLaunchWarningShown = false;
5423                                }
5424                            }
5425                        }, 4000);
5426                    }
5427                }
5428            });
5429        }
5430    }
5431
5432    @Override
5433    public boolean clearApplicationUserData(final String packageName,
5434            final IPackageDataObserver observer, int userId) {
5435        enforceNotIsolatedCaller("clearApplicationUserData");
5436        int uid = Binder.getCallingUid();
5437        int pid = Binder.getCallingPid();
5438        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5439                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5440
5441
5442        long callingId = Binder.clearCallingIdentity();
5443        try {
5444            IPackageManager pm = AppGlobals.getPackageManager();
5445            int pkgUid = -1;
5446            synchronized(this) {
5447                if (getPackageManagerInternalLocked().isPackageDataProtected(
5448                        userId, packageName)) {
5449                    throw new SecurityException(
5450                            "Cannot clear data for a protected package: " + packageName);
5451                }
5452
5453                try {
5454                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5455                } catch (RemoteException e) {
5456                }
5457                if (pkgUid == -1) {
5458                    Slog.w(TAG, "Invalid packageName: " + packageName);
5459                    if (observer != null) {
5460                        try {
5461                            observer.onRemoveCompleted(packageName, false);
5462                        } catch (RemoteException e) {
5463                            Slog.i(TAG, "Observer no longer exists.");
5464                        }
5465                    }
5466                    return false;
5467                }
5468                if (uid == pkgUid || checkComponentPermission(
5469                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5470                        pid, uid, -1, true)
5471                        == PackageManager.PERMISSION_GRANTED) {
5472                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5473                } else {
5474                    throw new SecurityException("PID " + pid + " does not have permission "
5475                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5476                                    + " of package " + packageName);
5477                }
5478
5479                // Remove all tasks match the cleared application package and user
5480                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5481                    final TaskRecord tr = mRecentTasks.get(i);
5482                    final String taskPackageName =
5483                            tr.getBaseIntent().getComponent().getPackageName();
5484                    if (tr.userId != userId) continue;
5485                    if (!taskPackageName.equals(packageName)) continue;
5486                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5487                }
5488            }
5489
5490            final int pkgUidF = pkgUid;
5491            final int userIdF = userId;
5492            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5493                @Override
5494                public void onRemoveCompleted(String packageName, boolean succeeded)
5495                        throws RemoteException {
5496                    synchronized (ActivityManagerService.this) {
5497                        finishForceStopPackageLocked(packageName, pkgUidF);
5498                    }
5499
5500                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5501                            Uri.fromParts("package", packageName, null));
5502                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5503                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5504                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5505                            null, null, 0, null, null, null, null, false, false, userIdF);
5506
5507                    if (observer != null) {
5508                        observer.onRemoveCompleted(packageName, succeeded);
5509                    }
5510                }
5511            };
5512
5513            try {
5514                // Clear application user data
5515                pm.clearApplicationUserData(packageName, localObserver, userId);
5516
5517                synchronized(this) {
5518                    // Remove all permissions granted from/to this package
5519                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5520                }
5521
5522                // Remove all zen rules created by this package; revoke it's zen access.
5523                INotificationManager inm = NotificationManager.getService();
5524                inm.removeAutomaticZenRules(packageName);
5525                inm.setNotificationPolicyAccessGranted(packageName, false);
5526
5527            } catch (RemoteException e) {
5528            }
5529        } finally {
5530            Binder.restoreCallingIdentity(callingId);
5531        }
5532        return true;
5533    }
5534
5535    @Override
5536    public void killBackgroundProcesses(final String packageName, int userId) {
5537        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5538                != PackageManager.PERMISSION_GRANTED &&
5539                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5540                        != PackageManager.PERMISSION_GRANTED) {
5541            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5542                    + Binder.getCallingPid()
5543                    + ", uid=" + Binder.getCallingUid()
5544                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5545            Slog.w(TAG, msg);
5546            throw new SecurityException(msg);
5547        }
5548
5549        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5550                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5551        long callingId = Binder.clearCallingIdentity();
5552        try {
5553            IPackageManager pm = AppGlobals.getPackageManager();
5554            synchronized(this) {
5555                int appId = -1;
5556                try {
5557                    appId = UserHandle.getAppId(
5558                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5559                } catch (RemoteException e) {
5560                }
5561                if (appId == -1) {
5562                    Slog.w(TAG, "Invalid packageName: " + packageName);
5563                    return;
5564                }
5565                killPackageProcessesLocked(packageName, appId, userId,
5566                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5567            }
5568        } finally {
5569            Binder.restoreCallingIdentity(callingId);
5570        }
5571    }
5572
5573    @Override
5574    public void killAllBackgroundProcesses() {
5575        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5576                != PackageManager.PERMISSION_GRANTED) {
5577            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5578                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5579                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5580            Slog.w(TAG, msg);
5581            throw new SecurityException(msg);
5582        }
5583
5584        final long callingId = Binder.clearCallingIdentity();
5585        try {
5586            synchronized (this) {
5587                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5588                final int NP = mProcessNames.getMap().size();
5589                for (int ip = 0; ip < NP; ip++) {
5590                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5591                    final int NA = apps.size();
5592                    for (int ia = 0; ia < NA; ia++) {
5593                        final ProcessRecord app = apps.valueAt(ia);
5594                        if (app.persistent) {
5595                            // We don't kill persistent processes.
5596                            continue;
5597                        }
5598                        if (app.removed) {
5599                            procs.add(app);
5600                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5601                            app.removed = true;
5602                            procs.add(app);
5603                        }
5604                    }
5605                }
5606
5607                final int N = procs.size();
5608                for (int i = 0; i < N; i++) {
5609                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5610                }
5611
5612                mAllowLowerMemLevel = true;
5613
5614                updateOomAdjLocked();
5615                doLowMemReportIfNeededLocked(null);
5616            }
5617        } finally {
5618            Binder.restoreCallingIdentity(callingId);
5619        }
5620    }
5621
5622    /**
5623     * Kills all background processes, except those matching any of the
5624     * specified properties.
5625     *
5626     * @param minTargetSdk the target SDK version at or above which to preserve
5627     *                     processes, or {@code -1} to ignore the target SDK
5628     * @param maxProcState the process state at or below which to preserve
5629     *                     processes, or {@code -1} to ignore the process state
5630     */
5631    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5632        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5633                != PackageManager.PERMISSION_GRANTED) {
5634            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5635                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5636                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5637            Slog.w(TAG, msg);
5638            throw new SecurityException(msg);
5639        }
5640
5641        final long callingId = Binder.clearCallingIdentity();
5642        try {
5643            synchronized (this) {
5644                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5645                final int NP = mProcessNames.getMap().size();
5646                for (int ip = 0; ip < NP; ip++) {
5647                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5648                    final int NA = apps.size();
5649                    for (int ia = 0; ia < NA; ia++) {
5650                        final ProcessRecord app = apps.valueAt(ia);
5651                        if (app.removed) {
5652                            procs.add(app);
5653                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5654                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5655                            app.removed = true;
5656                            procs.add(app);
5657                        }
5658                    }
5659                }
5660
5661                final int N = procs.size();
5662                for (int i = 0; i < N; i++) {
5663                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5664                }
5665            }
5666        } finally {
5667            Binder.restoreCallingIdentity(callingId);
5668        }
5669    }
5670
5671    @Override
5672    public void forceStopPackage(final String packageName, int userId) {
5673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5674                != PackageManager.PERMISSION_GRANTED) {
5675            String msg = "Permission Denial: forceStopPackage() from pid="
5676                    + Binder.getCallingPid()
5677                    + ", uid=" + Binder.getCallingUid()
5678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5679            Slog.w(TAG, msg);
5680            throw new SecurityException(msg);
5681        }
5682        final int callingPid = Binder.getCallingPid();
5683        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5684                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5685        long callingId = Binder.clearCallingIdentity();
5686        try {
5687            IPackageManager pm = AppGlobals.getPackageManager();
5688            synchronized(this) {
5689                int[] users = userId == UserHandle.USER_ALL
5690                        ? mUserController.getUsers() : new int[] { userId };
5691                for (int user : users) {
5692                    int pkgUid = -1;
5693                    try {
5694                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5695                                user);
5696                    } catch (RemoteException e) {
5697                    }
5698                    if (pkgUid == -1) {
5699                        Slog.w(TAG, "Invalid packageName: " + packageName);
5700                        continue;
5701                    }
5702                    try {
5703                        pm.setPackageStoppedState(packageName, true, user);
5704                    } catch (RemoteException e) {
5705                    } catch (IllegalArgumentException e) {
5706                        Slog.w(TAG, "Failed trying to unstop package "
5707                                + packageName + ": " + e);
5708                    }
5709                    if (mUserController.isUserRunningLocked(user, 0)) {
5710                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5711                        finishForceStopPackageLocked(packageName, pkgUid);
5712                    }
5713                }
5714            }
5715        } finally {
5716            Binder.restoreCallingIdentity(callingId);
5717        }
5718    }
5719
5720    @Override
5721    public void addPackageDependency(String packageName) {
5722        synchronized (this) {
5723            int callingPid = Binder.getCallingPid();
5724            if (callingPid == Process.myPid()) {
5725                //  Yeah, um, no.
5726                return;
5727            }
5728            ProcessRecord proc;
5729            synchronized (mPidsSelfLocked) {
5730                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5731            }
5732            if (proc != null) {
5733                if (proc.pkgDeps == null) {
5734                    proc.pkgDeps = new ArraySet<String>(1);
5735                }
5736                proc.pkgDeps.add(packageName);
5737            }
5738        }
5739    }
5740
5741    /*
5742     * The pkg name and app id have to be specified.
5743     */
5744    @Override
5745    public void killApplication(String pkg, int appId, int userId, String reason) {
5746        if (pkg == null) {
5747            return;
5748        }
5749        // Make sure the uid is valid.
5750        if (appId < 0) {
5751            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5752            return;
5753        }
5754        int callerUid = Binder.getCallingUid();
5755        // Only the system server can kill an application
5756        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5757            // Post an aysnc message to kill the application
5758            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5759            msg.arg1 = appId;
5760            msg.arg2 = userId;
5761            Bundle bundle = new Bundle();
5762            bundle.putString("pkg", pkg);
5763            bundle.putString("reason", reason);
5764            msg.obj = bundle;
5765            mHandler.sendMessage(msg);
5766        } else {
5767            throw new SecurityException(callerUid + " cannot kill pkg: " +
5768                    pkg);
5769        }
5770    }
5771
5772    @Override
5773    public void closeSystemDialogs(String reason) {
5774        enforceNotIsolatedCaller("closeSystemDialogs");
5775
5776        final int pid = Binder.getCallingPid();
5777        final int uid = Binder.getCallingUid();
5778        final long origId = Binder.clearCallingIdentity();
5779        try {
5780            synchronized (this) {
5781                // Only allow this from foreground processes, so that background
5782                // applications can't abuse it to prevent system UI from being shown.
5783                if (uid >= Process.FIRST_APPLICATION_UID) {
5784                    ProcessRecord proc;
5785                    synchronized (mPidsSelfLocked) {
5786                        proc = mPidsSelfLocked.get(pid);
5787                    }
5788                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5789                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5790                                + " from background process " + proc);
5791                        return;
5792                    }
5793                }
5794                closeSystemDialogsLocked(reason);
5795            }
5796        } finally {
5797            Binder.restoreCallingIdentity(origId);
5798        }
5799    }
5800
5801    void closeSystemDialogsLocked(String reason) {
5802        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5803        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5804                | Intent.FLAG_RECEIVER_FOREGROUND);
5805        if (reason != null) {
5806            intent.putExtra("reason", reason);
5807        }
5808        mWindowManager.closeSystemDialogs(reason);
5809
5810        mStackSupervisor.closeSystemDialogsLocked();
5811
5812        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5813                AppOpsManager.OP_NONE, null, false, false,
5814                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5815    }
5816
5817    @Override
5818    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5819        enforceNotIsolatedCaller("getProcessMemoryInfo");
5820        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5821        for (int i=pids.length-1; i>=0; i--) {
5822            ProcessRecord proc;
5823            int oomAdj;
5824            synchronized (this) {
5825                synchronized (mPidsSelfLocked) {
5826                    proc = mPidsSelfLocked.get(pids[i]);
5827                    oomAdj = proc != null ? proc.setAdj : 0;
5828                }
5829            }
5830            infos[i] = new Debug.MemoryInfo();
5831            Debug.getMemoryInfo(pids[i], infos[i]);
5832            if (proc != null) {
5833                synchronized (this) {
5834                    if (proc.thread != null && proc.setAdj == oomAdj) {
5835                        // Record this for posterity if the process has been stable.
5836                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5837                                infos[i].getTotalUss(), false, proc.pkgList);
5838                    }
5839                }
5840            }
5841        }
5842        return infos;
5843    }
5844
5845    @Override
5846    public long[] getProcessPss(int[] pids) {
5847        enforceNotIsolatedCaller("getProcessPss");
5848        long[] pss = new long[pids.length];
5849        for (int i=pids.length-1; i>=0; i--) {
5850            ProcessRecord proc;
5851            int oomAdj;
5852            synchronized (this) {
5853                synchronized (mPidsSelfLocked) {
5854                    proc = mPidsSelfLocked.get(pids[i]);
5855                    oomAdj = proc != null ? proc.setAdj : 0;
5856                }
5857            }
5858            long[] tmpUss = new long[1];
5859            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5860            if (proc != null) {
5861                synchronized (this) {
5862                    if (proc.thread != null && proc.setAdj == oomAdj) {
5863                        // Record this for posterity if the process has been stable.
5864                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5865                    }
5866                }
5867            }
5868        }
5869        return pss;
5870    }
5871
5872    @Override
5873    public void killApplicationProcess(String processName, int uid) {
5874        if (processName == null) {
5875            return;
5876        }
5877
5878        int callerUid = Binder.getCallingUid();
5879        // Only the system server can kill an application
5880        if (callerUid == Process.SYSTEM_UID) {
5881            synchronized (this) {
5882                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5883                if (app != null && app.thread != null) {
5884                    try {
5885                        app.thread.scheduleSuicide();
5886                    } catch (RemoteException e) {
5887                        // If the other end already died, then our work here is done.
5888                    }
5889                } else {
5890                    Slog.w(TAG, "Process/uid not found attempting kill of "
5891                            + processName + " / " + uid);
5892                }
5893            }
5894        } else {
5895            throw new SecurityException(callerUid + " cannot kill app process: " +
5896                    processName);
5897        }
5898    }
5899
5900    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5901        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5902                false, true, false, false, UserHandle.getUserId(uid), reason);
5903    }
5904
5905    private void finishForceStopPackageLocked(final String packageName, int uid) {
5906        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5907                Uri.fromParts("package", packageName, null));
5908        if (!mProcessesReady) {
5909            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5910                    | Intent.FLAG_RECEIVER_FOREGROUND);
5911        }
5912        intent.putExtra(Intent.EXTRA_UID, uid);
5913        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5914        broadcastIntentLocked(null, null, intent,
5915                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5916                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5917    }
5918
5919
5920    private final boolean killPackageProcessesLocked(String packageName, int appId,
5921            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5922            boolean doit, boolean evenPersistent, String reason) {
5923        ArrayList<ProcessRecord> procs = new ArrayList<>();
5924
5925        // Remove all processes this package may have touched: all with the
5926        // same UID (except for the system or root user), and all whose name
5927        // matches the package name.
5928        final int NP = mProcessNames.getMap().size();
5929        for (int ip=0; ip<NP; ip++) {
5930            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5931            final int NA = apps.size();
5932            for (int ia=0; ia<NA; ia++) {
5933                ProcessRecord app = apps.valueAt(ia);
5934                if (app.persistent && !evenPersistent) {
5935                    // we don't kill persistent processes
5936                    continue;
5937                }
5938                if (app.removed) {
5939                    if (doit) {
5940                        procs.add(app);
5941                    }
5942                    continue;
5943                }
5944
5945                // Skip process if it doesn't meet our oom adj requirement.
5946                if (app.setAdj < minOomAdj) {
5947                    continue;
5948                }
5949
5950                // If no package is specified, we call all processes under the
5951                // give user id.
5952                if (packageName == null) {
5953                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5954                        continue;
5955                    }
5956                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5957                        continue;
5958                    }
5959                // Package has been specified, we want to hit all processes
5960                // that match it.  We need to qualify this by the processes
5961                // that are running under the specified app and user ID.
5962                } else {
5963                    final boolean isDep = app.pkgDeps != null
5964                            && app.pkgDeps.contains(packageName);
5965                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5966                        continue;
5967                    }
5968                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5969                        continue;
5970                    }
5971                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5972                        continue;
5973                    }
5974                }
5975
5976                // Process has passed all conditions, kill it!
5977                if (!doit) {
5978                    return true;
5979                }
5980                app.removed = true;
5981                procs.add(app);
5982            }
5983        }
5984
5985        int N = procs.size();
5986        for (int i=0; i<N; i++) {
5987            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5988        }
5989        updateOomAdjLocked();
5990        return N > 0;
5991    }
5992
5993    private void cleanupDisabledPackageComponentsLocked(
5994            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5995
5996        Set<String> disabledClasses = null;
5997        boolean packageDisabled = false;
5998        IPackageManager pm = AppGlobals.getPackageManager();
5999
6000        if (changedClasses == null) {
6001            // Nothing changed...
6002            return;
6003        }
6004
6005        // Determine enable/disable state of the package and its components.
6006        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6007        for (int i = changedClasses.length - 1; i >= 0; i--) {
6008            final String changedClass = changedClasses[i];
6009
6010            if (changedClass.equals(packageName)) {
6011                try {
6012                    // Entire package setting changed
6013                    enabled = pm.getApplicationEnabledSetting(packageName,
6014                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6015                } catch (Exception e) {
6016                    // No such package/component; probably racing with uninstall.  In any
6017                    // event it means we have nothing further to do here.
6018                    return;
6019                }
6020                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6021                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6022                if (packageDisabled) {
6023                    // Entire package is disabled.
6024                    // No need to continue to check component states.
6025                    disabledClasses = null;
6026                    break;
6027                }
6028            } else {
6029                try {
6030                    enabled = pm.getComponentEnabledSetting(
6031                            new ComponentName(packageName, changedClass),
6032                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6033                } catch (Exception e) {
6034                    // As above, probably racing with uninstall.
6035                    return;
6036                }
6037                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6038                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6039                    if (disabledClasses == null) {
6040                        disabledClasses = new ArraySet<>(changedClasses.length);
6041                    }
6042                    disabledClasses.add(changedClass);
6043                }
6044            }
6045        }
6046
6047        if (!packageDisabled && disabledClasses == null) {
6048            // Nothing to do here...
6049            return;
6050        }
6051
6052        // Clean-up disabled activities.
6053        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6054                packageName, disabledClasses, true, false, userId) && mBooted) {
6055            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6056            mStackSupervisor.scheduleIdleLocked();
6057        }
6058
6059        // Clean-up disabled tasks
6060        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6061
6062        // Clean-up disabled services.
6063        mServices.bringDownDisabledPackageServicesLocked(
6064                packageName, disabledClasses, userId, false, killProcess, true);
6065
6066        // Clean-up disabled providers.
6067        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6068        mProviderMap.collectPackageProvidersLocked(
6069                packageName, disabledClasses, true, false, userId, providers);
6070        for (int i = providers.size() - 1; i >= 0; i--) {
6071            removeDyingProviderLocked(null, providers.get(i), true);
6072        }
6073
6074        // Clean-up disabled broadcast receivers.
6075        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6076            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6077                    packageName, disabledClasses, userId, true);
6078        }
6079
6080    }
6081
6082    final boolean clearBroadcastQueueForUserLocked(int userId) {
6083        boolean didSomething = false;
6084        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6085            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6086                    null, null, userId, true);
6087        }
6088        return didSomething;
6089    }
6090
6091    final boolean forceStopPackageLocked(String packageName, int appId,
6092            boolean callerWillRestart, boolean purgeCache, boolean doit,
6093            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6094        int i;
6095
6096        if (userId == UserHandle.USER_ALL && packageName == null) {
6097            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6098        }
6099
6100        if (appId < 0 && packageName != null) {
6101            try {
6102                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6103                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6104            } catch (RemoteException e) {
6105            }
6106        }
6107
6108        if (doit) {
6109            if (packageName != null) {
6110                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6111                        + " user=" + userId + ": " + reason);
6112            } else {
6113                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6114            }
6115
6116            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6117        }
6118
6119        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6120                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6121                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6122
6123        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6124                packageName, null, doit, evenPersistent, userId)) {
6125            if (!doit) {
6126                return true;
6127            }
6128            didSomething = true;
6129        }
6130
6131        if (mServices.bringDownDisabledPackageServicesLocked(
6132                packageName, null, userId, evenPersistent, true, doit)) {
6133            if (!doit) {
6134                return true;
6135            }
6136            didSomething = true;
6137        }
6138
6139        if (packageName == null) {
6140            // Remove all sticky broadcasts from this user.
6141            mStickyBroadcasts.remove(userId);
6142        }
6143
6144        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6145        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6146                userId, providers)) {
6147            if (!doit) {
6148                return true;
6149            }
6150            didSomething = true;
6151        }
6152        for (i = providers.size() - 1; i >= 0; i--) {
6153            removeDyingProviderLocked(null, providers.get(i), true);
6154        }
6155
6156        // Remove transient permissions granted from/to this package/user
6157        removeUriPermissionsForPackageLocked(packageName, userId, false);
6158
6159        if (doit) {
6160            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6161                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6162                        packageName, null, userId, doit);
6163            }
6164        }
6165
6166        if (packageName == null || uninstalling) {
6167            // Remove pending intents.  For now we only do this when force
6168            // stopping users, because we have some problems when doing this
6169            // for packages -- app widgets are not currently cleaned up for
6170            // such packages, so they can be left with bad pending intents.
6171            if (mIntentSenderRecords.size() > 0) {
6172                Iterator<WeakReference<PendingIntentRecord>> it
6173                        = mIntentSenderRecords.values().iterator();
6174                while (it.hasNext()) {
6175                    WeakReference<PendingIntentRecord> wpir = it.next();
6176                    if (wpir == null) {
6177                        it.remove();
6178                        continue;
6179                    }
6180                    PendingIntentRecord pir = wpir.get();
6181                    if (pir == null) {
6182                        it.remove();
6183                        continue;
6184                    }
6185                    if (packageName == null) {
6186                        // Stopping user, remove all objects for the user.
6187                        if (pir.key.userId != userId) {
6188                            // Not the same user, skip it.
6189                            continue;
6190                        }
6191                    } else {
6192                        if (UserHandle.getAppId(pir.uid) != appId) {
6193                            // Different app id, skip it.
6194                            continue;
6195                        }
6196                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6197                            // Different user, skip it.
6198                            continue;
6199                        }
6200                        if (!pir.key.packageName.equals(packageName)) {
6201                            // Different package, skip it.
6202                            continue;
6203                        }
6204                    }
6205                    if (!doit) {
6206                        return true;
6207                    }
6208                    didSomething = true;
6209                    it.remove();
6210                    pir.canceled = true;
6211                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6212                        pir.key.activity.pendingResults.remove(pir.ref);
6213                    }
6214                }
6215            }
6216        }
6217
6218        if (doit) {
6219            if (purgeCache && packageName != null) {
6220                AttributeCache ac = AttributeCache.instance();
6221                if (ac != null) {
6222                    ac.removePackage(packageName);
6223                }
6224            }
6225            if (mBooted) {
6226                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6227                mStackSupervisor.scheduleIdleLocked();
6228            }
6229        }
6230
6231        return didSomething;
6232    }
6233
6234    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6235        ProcessRecord old = mProcessNames.remove(name, uid);
6236        if (old != null) {
6237            old.uidRecord.numProcs--;
6238            if (old.uidRecord.numProcs == 0) {
6239                // No more processes using this uid, tell clients it is gone.
6240                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6241                        "No more processes in " + old.uidRecord);
6242                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6243                mActiveUids.remove(uid);
6244                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6245            }
6246            old.uidRecord = null;
6247        }
6248        mIsolatedProcesses.remove(uid);
6249        return old;
6250    }
6251
6252    private final void addProcessNameLocked(ProcessRecord proc) {
6253        // We shouldn't already have a process under this name, but just in case we
6254        // need to clean up whatever may be there now.
6255        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6256        if (old == proc && proc.persistent) {
6257            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6258            Slog.w(TAG, "Re-adding persistent process " + proc);
6259        } else if (old != null) {
6260            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6261        }
6262        UidRecord uidRec = mActiveUids.get(proc.uid);
6263        if (uidRec == null) {
6264            uidRec = new UidRecord(proc.uid);
6265            // This is the first appearance of the uid, report it now!
6266            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6267                    "Creating new process uid: " + uidRec);
6268            mActiveUids.put(proc.uid, uidRec);
6269            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6270            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6271        }
6272        proc.uidRecord = uidRec;
6273        uidRec.numProcs++;
6274        mProcessNames.put(proc.processName, proc.uid, proc);
6275        if (proc.isolated) {
6276            mIsolatedProcesses.put(proc.uid, proc);
6277        }
6278    }
6279
6280    boolean removeProcessLocked(ProcessRecord app,
6281            boolean callerWillRestart, boolean allowRestart, String reason) {
6282        final String name = app.processName;
6283        final int uid = app.uid;
6284        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6285            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6286
6287        ProcessRecord old = mProcessNames.get(name, uid);
6288        if (old != app) {
6289            // This process is no longer active, so nothing to do.
6290            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6291            return false;
6292        }
6293        removeProcessNameLocked(name, uid);
6294        if (mHeavyWeightProcess == app) {
6295            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6296                    mHeavyWeightProcess.userId, 0));
6297            mHeavyWeightProcess = null;
6298        }
6299        boolean needRestart = false;
6300        if (app.pid > 0 && app.pid != MY_PID) {
6301            int pid = app.pid;
6302            synchronized (mPidsSelfLocked) {
6303                mPidsSelfLocked.remove(pid);
6304                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6305            }
6306            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6307            if (app.isolated) {
6308                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6309            }
6310            boolean willRestart = false;
6311            if (app.persistent && !app.isolated) {
6312                if (!callerWillRestart) {
6313                    willRestart = true;
6314                } else {
6315                    needRestart = true;
6316                }
6317            }
6318            app.kill(reason, true);
6319            handleAppDiedLocked(app, willRestart, allowRestart);
6320            if (willRestart) {
6321                removeLruProcessLocked(app);
6322                addAppLocked(app.info, false, null /* ABI override */);
6323            }
6324        } else {
6325            mRemovedProcesses.add(app);
6326        }
6327
6328        return needRestart;
6329    }
6330
6331    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6332        cleanupAppInLaunchingProvidersLocked(app, true);
6333        removeProcessLocked(app, false, true, "timeout publishing content providers");
6334    }
6335
6336    private final void processStartTimedOutLocked(ProcessRecord app) {
6337        final int pid = app.pid;
6338        boolean gone = false;
6339        synchronized (mPidsSelfLocked) {
6340            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6341            if (knownApp != null && knownApp.thread == null) {
6342                mPidsSelfLocked.remove(pid);
6343                gone = true;
6344            }
6345        }
6346
6347        if (gone) {
6348            Slog.w(TAG, "Process " + app + " failed to attach");
6349            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6350                    pid, app.uid, app.processName);
6351            removeProcessNameLocked(app.processName, app.uid);
6352            if (mHeavyWeightProcess == app) {
6353                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6354                        mHeavyWeightProcess.userId, 0));
6355                mHeavyWeightProcess = null;
6356            }
6357            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6358            if (app.isolated) {
6359                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6360            }
6361            // Take care of any launching providers waiting for this process.
6362            cleanupAppInLaunchingProvidersLocked(app, true);
6363            // Take care of any services that are waiting for the process.
6364            mServices.processStartTimedOutLocked(app);
6365            app.kill("start timeout", true);
6366            removeLruProcessLocked(app);
6367            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6368                Slog.w(TAG, "Unattached app died before backup, skipping");
6369                try {
6370                    IBackupManager bm = IBackupManager.Stub.asInterface(
6371                            ServiceManager.getService(Context.BACKUP_SERVICE));
6372                    bm.agentDisconnected(app.info.packageName);
6373                } catch (RemoteException e) {
6374                    // Can't happen; the backup manager is local
6375                }
6376            }
6377            if (isPendingBroadcastProcessLocked(pid)) {
6378                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6379                skipPendingBroadcastLocked(pid);
6380            }
6381        } else {
6382            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6383        }
6384    }
6385
6386    private final boolean attachApplicationLocked(IApplicationThread thread,
6387            int pid) {
6388
6389        // Find the application record that is being attached...  either via
6390        // the pid if we are running in multiple processes, or just pull the
6391        // next app record if we are emulating process with anonymous threads.
6392        ProcessRecord app;
6393        if (pid != MY_PID && pid >= 0) {
6394            synchronized (mPidsSelfLocked) {
6395                app = mPidsSelfLocked.get(pid);
6396            }
6397        } else {
6398            app = null;
6399        }
6400
6401        if (app == null) {
6402            Slog.w(TAG, "No pending application record for pid " + pid
6403                    + " (IApplicationThread " + thread + "); dropping process");
6404            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6405            if (pid > 0 && pid != MY_PID) {
6406                Process.killProcessQuiet(pid);
6407                //TODO: killProcessGroup(app.info.uid, pid);
6408            } else {
6409                try {
6410                    thread.scheduleExit();
6411                } catch (Exception e) {
6412                    // Ignore exceptions.
6413                }
6414            }
6415            return false;
6416        }
6417
6418        // If this application record is still attached to a previous
6419        // process, clean it up now.
6420        if (app.thread != null) {
6421            handleAppDiedLocked(app, true, true);
6422        }
6423
6424        // Tell the process all about itself.
6425
6426        if (DEBUG_ALL) Slog.v(
6427                TAG, "Binding process pid " + pid + " to record " + app);
6428
6429        final String processName = app.processName;
6430        try {
6431            AppDeathRecipient adr = new AppDeathRecipient(
6432                    app, pid, thread);
6433            thread.asBinder().linkToDeath(adr, 0);
6434            app.deathRecipient = adr;
6435        } catch (RemoteException e) {
6436            app.resetPackageList(mProcessStats);
6437            startProcessLocked(app, "link fail", processName);
6438            return false;
6439        }
6440
6441        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6442
6443        app.makeActive(thread, mProcessStats);
6444        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6445        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6446        app.forcingToForeground = null;
6447        updateProcessForegroundLocked(app, false, false);
6448        app.hasShownUi = false;
6449        app.debugging = false;
6450        app.cached = false;
6451        app.killedByAm = false;
6452
6453        // We carefully use the same state that PackageManager uses for
6454        // filtering, since we use this flag to decide if we need to install
6455        // providers when user is unlocked later
6456        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6457
6458        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6459
6460        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6461        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6462
6463        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6464            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6465            msg.obj = app;
6466            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6467        }
6468
6469        if (!normalMode) {
6470            Slog.i(TAG, "Launching preboot mode app: " + app);
6471        }
6472
6473        if (DEBUG_ALL) Slog.v(
6474            TAG, "New app record " + app
6475            + " thread=" + thread.asBinder() + " pid=" + pid);
6476        try {
6477            int testMode = IApplicationThread.DEBUG_OFF;
6478            if (mDebugApp != null && mDebugApp.equals(processName)) {
6479                testMode = mWaitForDebugger
6480                    ? IApplicationThread.DEBUG_WAIT
6481                    : IApplicationThread.DEBUG_ON;
6482                app.debugging = true;
6483                if (mDebugTransient) {
6484                    mDebugApp = mOrigDebugApp;
6485                    mWaitForDebugger = mOrigWaitForDebugger;
6486                }
6487            }
6488            String profileFile = app.instrumentationProfileFile;
6489            ParcelFileDescriptor profileFd = null;
6490            int samplingInterval = 0;
6491            boolean profileAutoStop = false;
6492            if (mProfileApp != null && mProfileApp.equals(processName)) {
6493                mProfileProc = app;
6494                profileFile = mProfileFile;
6495                profileFd = mProfileFd;
6496                samplingInterval = mSamplingInterval;
6497                profileAutoStop = mAutoStopProfiler;
6498            }
6499            boolean enableTrackAllocation = false;
6500            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6501                enableTrackAllocation = true;
6502                mTrackAllocationApp = null;
6503            }
6504
6505            // If the app is being launched for restore or full backup, set it up specially
6506            boolean isRestrictedBackupMode = false;
6507            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6508                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6509                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6510                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6511                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6512            }
6513
6514            if (app.instrumentationClass != null) {
6515                notifyPackageUse(app.instrumentationClass.getPackageName(),
6516                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6517            }
6518            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6519                    + processName + " with config " + mConfiguration);
6520            ApplicationInfo appInfo = app.instrumentationInfo != null
6521                    ? app.instrumentationInfo : app.info;
6522            app.compat = compatibilityInfoForPackageLocked(appInfo);
6523            if (profileFd != null) {
6524                profileFd = profileFd.dup();
6525            }
6526            ProfilerInfo profilerInfo = profileFile == null ? null
6527                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6528            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6529                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6530                    app.instrumentationUiAutomationConnection, testMode,
6531                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6532                    isRestrictedBackupMode || !normalMode, app.persistent,
6533                    new Configuration(mConfiguration), app.compat,
6534                    getCommonServicesLocked(app.isolated),
6535                    mCoreSettingsObserver.getCoreSettingsLocked());
6536            updateLruProcessLocked(app, false, null);
6537            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6538        } catch (Exception e) {
6539            // todo: Yikes!  What should we do?  For now we will try to
6540            // start another process, but that could easily get us in
6541            // an infinite loop of restarting processes...
6542            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6543
6544            app.resetPackageList(mProcessStats);
6545            app.unlinkDeathRecipient();
6546            startProcessLocked(app, "bind fail", processName);
6547            return false;
6548        }
6549
6550        // Remove this record from the list of starting applications.
6551        mPersistentStartingProcesses.remove(app);
6552        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6553                "Attach application locked removing on hold: " + app);
6554        mProcessesOnHold.remove(app);
6555
6556        boolean badApp = false;
6557        boolean didSomething = false;
6558
6559        // See if the top visible activity is waiting to run in this process...
6560        if (normalMode) {
6561            try {
6562                if (mStackSupervisor.attachApplicationLocked(app)) {
6563                    didSomething = true;
6564                }
6565            } catch (Exception e) {
6566                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6567                badApp = true;
6568            }
6569        }
6570
6571        // Find any services that should be running in this process...
6572        if (!badApp) {
6573            try {
6574                didSomething |= mServices.attachApplicationLocked(app, processName);
6575            } catch (Exception e) {
6576                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6577                badApp = true;
6578            }
6579        }
6580
6581        // Check if a next-broadcast receiver is in this process...
6582        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6583            try {
6584                didSomething |= sendPendingBroadcastsLocked(app);
6585            } catch (Exception e) {
6586                // If the app died trying to launch the receiver we declare it 'bad'
6587                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6588                badApp = true;
6589            }
6590        }
6591
6592        // Check whether the next backup agent is in this process...
6593        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6594            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6595                    "New app is backup target, launching agent for " + app);
6596            notifyPackageUse(mBackupTarget.appInfo.packageName,
6597                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6598            try {
6599                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6600                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6601                        mBackupTarget.backupMode);
6602            } catch (Exception e) {
6603                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6604                badApp = true;
6605            }
6606        }
6607
6608        if (badApp) {
6609            app.kill("error during init", true);
6610            handleAppDiedLocked(app, false, true);
6611            return false;
6612        }
6613
6614        if (!didSomething) {
6615            updateOomAdjLocked();
6616        }
6617
6618        return true;
6619    }
6620
6621    @Override
6622    public final void attachApplication(IApplicationThread thread) {
6623        synchronized (this) {
6624            int callingPid = Binder.getCallingPid();
6625            final long origId = Binder.clearCallingIdentity();
6626            attachApplicationLocked(thread, callingPid);
6627            Binder.restoreCallingIdentity(origId);
6628        }
6629    }
6630
6631    @Override
6632    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6633        final long origId = Binder.clearCallingIdentity();
6634        synchronized (this) {
6635            ActivityStack stack = ActivityRecord.getStackLocked(token);
6636            if (stack != null) {
6637                ActivityRecord r =
6638                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6639                if (stopProfiling) {
6640                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6641                        try {
6642                            mProfileFd.close();
6643                        } catch (IOException e) {
6644                        }
6645                        clearProfilerLocked();
6646                    }
6647                }
6648            }
6649        }
6650        Binder.restoreCallingIdentity(origId);
6651    }
6652
6653    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6654        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6655                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6656    }
6657
6658    void enableScreenAfterBoot() {
6659        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6660                SystemClock.uptimeMillis());
6661        mWindowManager.enableScreenAfterBoot();
6662
6663        synchronized (this) {
6664            updateEventDispatchingLocked();
6665        }
6666    }
6667
6668    @Override
6669    public void showBootMessage(final CharSequence msg, final boolean always) {
6670        if (Binder.getCallingUid() != Process.myUid()) {
6671            // These days only the core system can call this, so apps can't get in
6672            // the way of what we show about running them.
6673        }
6674        mWindowManager.showBootMessage(msg, always);
6675    }
6676
6677    @Override
6678    public void keyguardWaitingForActivityDrawn() {
6679        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6680        final long token = Binder.clearCallingIdentity();
6681        try {
6682            synchronized (this) {
6683                if (DEBUG_LOCKSCREEN) logLockScreen("");
6684                mWindowManager.keyguardWaitingForActivityDrawn();
6685                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6686                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6687                    updateSleepIfNeededLocked();
6688                }
6689            }
6690        } finally {
6691            Binder.restoreCallingIdentity(token);
6692        }
6693    }
6694
6695    @Override
6696    public void keyguardGoingAway(int flags) {
6697        enforceNotIsolatedCaller("keyguardGoingAway");
6698        final long token = Binder.clearCallingIdentity();
6699        try {
6700            synchronized (this) {
6701                if (DEBUG_LOCKSCREEN) logLockScreen("");
6702                mWindowManager.keyguardGoingAway(flags);
6703                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6704                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6705                    updateSleepIfNeededLocked();
6706
6707                    // Some stack visibility might change (e.g. docked stack)
6708                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6709                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6710                }
6711            }
6712        } finally {
6713            Binder.restoreCallingIdentity(token);
6714        }
6715    }
6716
6717    final void finishBooting() {
6718        synchronized (this) {
6719            if (!mBootAnimationComplete) {
6720                mCallFinishBooting = true;
6721                return;
6722            }
6723            mCallFinishBooting = false;
6724        }
6725
6726        ArraySet<String> completedIsas = new ArraySet<String>();
6727        for (String abi : Build.SUPPORTED_ABIS) {
6728            Process.establishZygoteConnectionForAbi(abi);
6729            final String instructionSet = VMRuntime.getInstructionSet(abi);
6730            if (!completedIsas.contains(instructionSet)) {
6731                try {
6732                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6733                } catch (InstallerException e) {
6734                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6735                            e.getMessage() +")");
6736                }
6737                completedIsas.add(instructionSet);
6738            }
6739        }
6740
6741        IntentFilter pkgFilter = new IntentFilter();
6742        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6743        pkgFilter.addDataScheme("package");
6744        mContext.registerReceiver(new BroadcastReceiver() {
6745            @Override
6746            public void onReceive(Context context, Intent intent) {
6747                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6748                if (pkgs != null) {
6749                    for (String pkg : pkgs) {
6750                        synchronized (ActivityManagerService.this) {
6751                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6752                                    0, "query restart")) {
6753                                setResultCode(Activity.RESULT_OK);
6754                                return;
6755                            }
6756                        }
6757                    }
6758                }
6759            }
6760        }, pkgFilter);
6761
6762        IntentFilter dumpheapFilter = new IntentFilter();
6763        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6764        mContext.registerReceiver(new BroadcastReceiver() {
6765            @Override
6766            public void onReceive(Context context, Intent intent) {
6767                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6768                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6769                } else {
6770                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6771                }
6772            }
6773        }, dumpheapFilter);
6774
6775        // Let system services know.
6776        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6777
6778        synchronized (this) {
6779            // Ensure that any processes we had put on hold are now started
6780            // up.
6781            final int NP = mProcessesOnHold.size();
6782            if (NP > 0) {
6783                ArrayList<ProcessRecord> procs =
6784                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6785                for (int ip=0; ip<NP; ip++) {
6786                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6787                            + procs.get(ip));
6788                    startProcessLocked(procs.get(ip), "on-hold", null);
6789                }
6790            }
6791
6792            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6793                // Start looking for apps that are abusing wake locks.
6794                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6795                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6796                // Tell anyone interested that we are done booting!
6797                SystemProperties.set("sys.boot_completed", "1");
6798
6799                // And trigger dev.bootcomplete if we are not showing encryption progress
6800                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6801                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6802                    SystemProperties.set("dev.bootcomplete", "1");
6803                }
6804                mUserController.sendBootCompletedLocked(
6805                        new IIntentReceiver.Stub() {
6806                            @Override
6807                            public void performReceive(Intent intent, int resultCode,
6808                                    String data, Bundle extras, boolean ordered,
6809                                    boolean sticky, int sendingUser) {
6810                                synchronized (ActivityManagerService.this) {
6811                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6812                                            true, false);
6813                                }
6814                            }
6815                        });
6816                scheduleStartProfilesLocked();
6817            }
6818        }
6819    }
6820
6821    @Override
6822    public void bootAnimationComplete() {
6823        final boolean callFinishBooting;
6824        synchronized (this) {
6825            callFinishBooting = mCallFinishBooting;
6826            mBootAnimationComplete = true;
6827        }
6828        if (callFinishBooting) {
6829            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6830            finishBooting();
6831            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6832        }
6833    }
6834
6835    final void ensureBootCompleted() {
6836        boolean booting;
6837        boolean enableScreen;
6838        synchronized (this) {
6839            booting = mBooting;
6840            mBooting = false;
6841            enableScreen = !mBooted;
6842            mBooted = true;
6843        }
6844
6845        if (booting) {
6846            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6847            finishBooting();
6848            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6849        }
6850
6851        if (enableScreen) {
6852            enableScreenAfterBoot();
6853        }
6854    }
6855
6856    @Override
6857    public final void activityResumed(IBinder token) {
6858        final long origId = Binder.clearCallingIdentity();
6859        synchronized(this) {
6860            ActivityStack stack = ActivityRecord.getStackLocked(token);
6861            if (stack != null) {
6862                stack.activityResumedLocked(token);
6863            }
6864        }
6865        Binder.restoreCallingIdentity(origId);
6866    }
6867
6868    @Override
6869    public final void activityPaused(IBinder token) {
6870        final long origId = Binder.clearCallingIdentity();
6871        synchronized(this) {
6872            ActivityStack stack = ActivityRecord.getStackLocked(token);
6873            if (stack != null) {
6874                stack.activityPausedLocked(token, false);
6875            }
6876        }
6877        Binder.restoreCallingIdentity(origId);
6878    }
6879
6880    @Override
6881    public final void activityStopped(IBinder token, Bundle icicle,
6882            PersistableBundle persistentState, CharSequence description) {
6883        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6884
6885        // Refuse possible leaked file descriptors
6886        if (icicle != null && icicle.hasFileDescriptors()) {
6887            throw new IllegalArgumentException("File descriptors passed in Bundle");
6888        }
6889
6890        final long origId = Binder.clearCallingIdentity();
6891
6892        synchronized (this) {
6893            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6894            if (r != null) {
6895                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6896            }
6897        }
6898
6899        trimApplications();
6900
6901        Binder.restoreCallingIdentity(origId);
6902    }
6903
6904    @Override
6905    public final void activityDestroyed(IBinder token) {
6906        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6907        synchronized (this) {
6908            ActivityStack stack = ActivityRecord.getStackLocked(token);
6909            if (stack != null) {
6910                stack.activityDestroyedLocked(token, "activityDestroyed");
6911            }
6912        }
6913    }
6914
6915    @Override
6916    public final void activityRelaunched(IBinder token) {
6917        final long origId = Binder.clearCallingIdentity();
6918        synchronized (this) {
6919            mStackSupervisor.activityRelaunchedLocked(token);
6920        }
6921        Binder.restoreCallingIdentity(origId);
6922    }
6923
6924    @Override
6925    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6926            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6927        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6928                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6929        synchronized (this) {
6930            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6931            if (record == null) {
6932                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6933                        + "found for: " + token);
6934            }
6935            record.setSizeConfigurations(horizontalSizeConfiguration,
6936                    verticalSizeConfigurations, smallestSizeConfigurations);
6937        }
6938    }
6939
6940    @Override
6941    public final void backgroundResourcesReleased(IBinder token) {
6942        final long origId = Binder.clearCallingIdentity();
6943        try {
6944            synchronized (this) {
6945                ActivityStack stack = ActivityRecord.getStackLocked(token);
6946                if (stack != null) {
6947                    stack.backgroundResourcesReleased();
6948                }
6949            }
6950        } finally {
6951            Binder.restoreCallingIdentity(origId);
6952        }
6953    }
6954
6955    @Override
6956    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6957        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6958    }
6959
6960    @Override
6961    public final void notifyEnterAnimationComplete(IBinder token) {
6962        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6963    }
6964
6965    @Override
6966    public String getCallingPackage(IBinder token) {
6967        synchronized (this) {
6968            ActivityRecord r = getCallingRecordLocked(token);
6969            return r != null ? r.info.packageName : null;
6970        }
6971    }
6972
6973    @Override
6974    public ComponentName getCallingActivity(IBinder token) {
6975        synchronized (this) {
6976            ActivityRecord r = getCallingRecordLocked(token);
6977            return r != null ? r.intent.getComponent() : null;
6978        }
6979    }
6980
6981    private ActivityRecord getCallingRecordLocked(IBinder token) {
6982        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6983        if (r == null) {
6984            return null;
6985        }
6986        return r.resultTo;
6987    }
6988
6989    @Override
6990    public ComponentName getActivityClassForToken(IBinder token) {
6991        synchronized(this) {
6992            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6993            if (r == null) {
6994                return null;
6995            }
6996            return r.intent.getComponent();
6997        }
6998    }
6999
7000    @Override
7001    public String getPackageForToken(IBinder token) {
7002        synchronized(this) {
7003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7004            if (r == null) {
7005                return null;
7006            }
7007            return r.packageName;
7008        }
7009    }
7010
7011    @Override
7012    public boolean isRootVoiceInteraction(IBinder token) {
7013        synchronized(this) {
7014            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7015            if (r == null) {
7016                return false;
7017            }
7018            return r.rootVoiceInteraction;
7019        }
7020    }
7021
7022    @Override
7023    public IIntentSender getIntentSender(int type,
7024            String packageName, IBinder token, String resultWho,
7025            int requestCode, Intent[] intents, String[] resolvedTypes,
7026            int flags, Bundle bOptions, int userId) {
7027        enforceNotIsolatedCaller("getIntentSender");
7028        // Refuse possible leaked file descriptors
7029        if (intents != null) {
7030            if (intents.length < 1) {
7031                throw new IllegalArgumentException("Intents array length must be >= 1");
7032            }
7033            for (int i=0; i<intents.length; i++) {
7034                Intent intent = intents[i];
7035                if (intent != null) {
7036                    if (intent.hasFileDescriptors()) {
7037                        throw new IllegalArgumentException("File descriptors passed in Intent");
7038                    }
7039                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7040                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7041                        throw new IllegalArgumentException(
7042                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7043                    }
7044                    intents[i] = new Intent(intent);
7045                }
7046            }
7047            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7048                throw new IllegalArgumentException(
7049                        "Intent array length does not match resolvedTypes length");
7050            }
7051        }
7052        if (bOptions != null) {
7053            if (bOptions.hasFileDescriptors()) {
7054                throw new IllegalArgumentException("File descriptors passed in options");
7055            }
7056        }
7057
7058        synchronized(this) {
7059            int callingUid = Binder.getCallingUid();
7060            int origUserId = userId;
7061            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7062                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7063                    ALLOW_NON_FULL, "getIntentSender", null);
7064            if (origUserId == UserHandle.USER_CURRENT) {
7065                // We don't want to evaluate this until the pending intent is
7066                // actually executed.  However, we do want to always do the
7067                // security checking for it above.
7068                userId = UserHandle.USER_CURRENT;
7069            }
7070            try {
7071                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7072                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7073                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7074                    if (!UserHandle.isSameApp(callingUid, uid)) {
7075                        String msg = "Permission Denial: getIntentSender() from pid="
7076                            + Binder.getCallingPid()
7077                            + ", uid=" + Binder.getCallingUid()
7078                            + ", (need uid=" + uid + ")"
7079                            + " is not allowed to send as package " + packageName;
7080                        Slog.w(TAG, msg);
7081                        throw new SecurityException(msg);
7082                    }
7083                }
7084
7085                return getIntentSenderLocked(type, packageName, callingUid, userId,
7086                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7087
7088            } catch (RemoteException e) {
7089                throw new SecurityException(e);
7090            }
7091        }
7092    }
7093
7094    IIntentSender getIntentSenderLocked(int type, String packageName,
7095            int callingUid, int userId, IBinder token, String resultWho,
7096            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7097            Bundle bOptions) {
7098        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7099        ActivityRecord activity = null;
7100        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7101            activity = ActivityRecord.isInStackLocked(token);
7102            if (activity == null) {
7103                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7104                return null;
7105            }
7106            if (activity.finishing) {
7107                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7108                return null;
7109            }
7110        }
7111
7112        // We're going to be splicing together extras before sending, so we're
7113        // okay poking into any contained extras.
7114        if (intents != null) {
7115            for (int i = 0; i < intents.length; i++) {
7116                intents[i].setDefusable(true);
7117            }
7118        }
7119        Bundle.setDefusable(bOptions, true);
7120
7121        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7122        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7123        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7124        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7125                |PendingIntent.FLAG_UPDATE_CURRENT);
7126
7127        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7128                type, packageName, activity, resultWho,
7129                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7130        WeakReference<PendingIntentRecord> ref;
7131        ref = mIntentSenderRecords.get(key);
7132        PendingIntentRecord rec = ref != null ? ref.get() : null;
7133        if (rec != null) {
7134            if (!cancelCurrent) {
7135                if (updateCurrent) {
7136                    if (rec.key.requestIntent != null) {
7137                        rec.key.requestIntent.replaceExtras(intents != null ?
7138                                intents[intents.length - 1] : null);
7139                    }
7140                    if (intents != null) {
7141                        intents[intents.length-1] = rec.key.requestIntent;
7142                        rec.key.allIntents = intents;
7143                        rec.key.allResolvedTypes = resolvedTypes;
7144                    } else {
7145                        rec.key.allIntents = null;
7146                        rec.key.allResolvedTypes = null;
7147                    }
7148                }
7149                return rec;
7150            }
7151            rec.canceled = true;
7152            mIntentSenderRecords.remove(key);
7153        }
7154        if (noCreate) {
7155            return rec;
7156        }
7157        rec = new PendingIntentRecord(this, key, callingUid);
7158        mIntentSenderRecords.put(key, rec.ref);
7159        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7160            if (activity.pendingResults == null) {
7161                activity.pendingResults
7162                        = new HashSet<WeakReference<PendingIntentRecord>>();
7163            }
7164            activity.pendingResults.add(rec.ref);
7165        }
7166        return rec;
7167    }
7168
7169    @Override
7170    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7171            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7172        if (target instanceof PendingIntentRecord) {
7173            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7174                    finishedReceiver, requiredPermission, options);
7175        } else {
7176            if (intent == null) {
7177                // Weird case: someone has given us their own custom IIntentSender, and now
7178                // they have someone else trying to send to it but of course this isn't
7179                // really a PendingIntent, so there is no base Intent, and the caller isn't
7180                // supplying an Intent... but we never want to dispatch a null Intent to
7181                // a receiver, so um...  let's make something up.
7182                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7183                intent = new Intent(Intent.ACTION_MAIN);
7184            }
7185            try {
7186                target.send(code, intent, resolvedType, null, requiredPermission, options);
7187            } catch (RemoteException e) {
7188            }
7189            // Platform code can rely on getting a result back when the send is done, but if
7190            // this intent sender is from outside of the system we can't rely on it doing that.
7191            // So instead we don't give it the result receiver, and instead just directly
7192            // report the finish immediately.
7193            if (finishedReceiver != null) {
7194                try {
7195                    finishedReceiver.performReceive(intent, 0,
7196                            null, null, false, false, UserHandle.getCallingUserId());
7197                } catch (RemoteException e) {
7198                }
7199            }
7200            return 0;
7201        }
7202    }
7203
7204    /**
7205     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7206     *
7207     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7208     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7209     */
7210    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7211        if (DEBUG_WHITELISTS) {
7212            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7213                    + targetUid + ", " + duration + ")");
7214        }
7215        synchronized (mPidsSelfLocked) {
7216            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7217            if (pr == null) {
7218                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7219                return;
7220            }
7221            if (!pr.whitelistManager) {
7222                if (DEBUG_WHITELISTS) {
7223                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7224                            + callerPid + " is not allowed");
7225                }
7226                return;
7227            }
7228        }
7229
7230        final long token = Binder.clearCallingIdentity();
7231        try {
7232            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7233                    true, "pe from uid:" + callerUid);
7234        } finally {
7235            Binder.restoreCallingIdentity(token);
7236        }
7237    }
7238
7239    @Override
7240    public void cancelIntentSender(IIntentSender sender) {
7241        if (!(sender instanceof PendingIntentRecord)) {
7242            return;
7243        }
7244        synchronized(this) {
7245            PendingIntentRecord rec = (PendingIntentRecord)sender;
7246            try {
7247                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7248                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7249                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7250                    String msg = "Permission Denial: cancelIntentSender() from pid="
7251                        + Binder.getCallingPid()
7252                        + ", uid=" + Binder.getCallingUid()
7253                        + " is not allowed to cancel packges "
7254                        + rec.key.packageName;
7255                    Slog.w(TAG, msg);
7256                    throw new SecurityException(msg);
7257                }
7258            } catch (RemoteException e) {
7259                throw new SecurityException(e);
7260            }
7261            cancelIntentSenderLocked(rec, true);
7262        }
7263    }
7264
7265    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7266        rec.canceled = true;
7267        mIntentSenderRecords.remove(rec.key);
7268        if (cleanActivity && rec.key.activity != null) {
7269            rec.key.activity.pendingResults.remove(rec.ref);
7270        }
7271    }
7272
7273    @Override
7274    public String getPackageForIntentSender(IIntentSender pendingResult) {
7275        if (!(pendingResult instanceof PendingIntentRecord)) {
7276            return null;
7277        }
7278        try {
7279            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7280            return res.key.packageName;
7281        } catch (ClassCastException e) {
7282        }
7283        return null;
7284    }
7285
7286    @Override
7287    public int getUidForIntentSender(IIntentSender sender) {
7288        if (sender instanceof PendingIntentRecord) {
7289            try {
7290                PendingIntentRecord res = (PendingIntentRecord)sender;
7291                return res.uid;
7292            } catch (ClassCastException e) {
7293            }
7294        }
7295        return -1;
7296    }
7297
7298    @Override
7299    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7300        if (!(pendingResult instanceof PendingIntentRecord)) {
7301            return false;
7302        }
7303        try {
7304            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7305            if (res.key.allIntents == null) {
7306                return false;
7307            }
7308            for (int i=0; i<res.key.allIntents.length; i++) {
7309                Intent intent = res.key.allIntents[i];
7310                if (intent.getPackage() != null && intent.getComponent() != null) {
7311                    return false;
7312                }
7313            }
7314            return true;
7315        } catch (ClassCastException e) {
7316        }
7317        return false;
7318    }
7319
7320    @Override
7321    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7322        if (!(pendingResult instanceof PendingIntentRecord)) {
7323            return false;
7324        }
7325        try {
7326            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7327            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7328                return true;
7329            }
7330            return false;
7331        } catch (ClassCastException e) {
7332        }
7333        return false;
7334    }
7335
7336    @Override
7337    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7338        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7339                "getIntentForIntentSender()");
7340        if (!(pendingResult instanceof PendingIntentRecord)) {
7341            return null;
7342        }
7343        try {
7344            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7345            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7346        } catch (ClassCastException e) {
7347        }
7348        return null;
7349    }
7350
7351    @Override
7352    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7353        if (!(pendingResult instanceof PendingIntentRecord)) {
7354            return null;
7355        }
7356        try {
7357            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7358            synchronized (this) {
7359                return getTagForIntentSenderLocked(res, prefix);
7360            }
7361        } catch (ClassCastException e) {
7362        }
7363        return null;
7364    }
7365
7366    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7367        final Intent intent = res.key.requestIntent;
7368        if (intent != null) {
7369            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7370                    || res.lastTagPrefix.equals(prefix))) {
7371                return res.lastTag;
7372            }
7373            res.lastTagPrefix = prefix;
7374            final StringBuilder sb = new StringBuilder(128);
7375            if (prefix != null) {
7376                sb.append(prefix);
7377            }
7378            if (intent.getAction() != null) {
7379                sb.append(intent.getAction());
7380            } else if (intent.getComponent() != null) {
7381                intent.getComponent().appendShortString(sb);
7382            } else {
7383                sb.append("?");
7384            }
7385            return res.lastTag = sb.toString();
7386        }
7387        return null;
7388    }
7389
7390    @Override
7391    public void setProcessLimit(int max) {
7392        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7393                "setProcessLimit()");
7394        synchronized (this) {
7395            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7396            mProcessLimitOverride = max;
7397        }
7398        trimApplications();
7399    }
7400
7401    @Override
7402    public int getProcessLimit() {
7403        synchronized (this) {
7404            return mProcessLimitOverride;
7405        }
7406    }
7407
7408    void foregroundTokenDied(ForegroundToken token) {
7409        synchronized (ActivityManagerService.this) {
7410            synchronized (mPidsSelfLocked) {
7411                ForegroundToken cur
7412                    = mForegroundProcesses.get(token.pid);
7413                if (cur != token) {
7414                    return;
7415                }
7416                mForegroundProcesses.remove(token.pid);
7417                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7418                if (pr == null) {
7419                    return;
7420                }
7421                pr.forcingToForeground = null;
7422                updateProcessForegroundLocked(pr, false, false);
7423            }
7424            updateOomAdjLocked();
7425        }
7426    }
7427
7428    @Override
7429    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7430        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7431                "setProcessForeground()");
7432        synchronized(this) {
7433            boolean changed = false;
7434
7435            synchronized (mPidsSelfLocked) {
7436                ProcessRecord pr = mPidsSelfLocked.get(pid);
7437                if (pr == null && isForeground) {
7438                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7439                    return;
7440                }
7441                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7442                if (oldToken != null) {
7443                    oldToken.token.unlinkToDeath(oldToken, 0);
7444                    mForegroundProcesses.remove(pid);
7445                    if (pr != null) {
7446                        pr.forcingToForeground = null;
7447                    }
7448                    changed = true;
7449                }
7450                if (isForeground && token != null) {
7451                    ForegroundToken newToken = new ForegroundToken() {
7452                        @Override
7453                        public void binderDied() {
7454                            foregroundTokenDied(this);
7455                        }
7456                    };
7457                    newToken.pid = pid;
7458                    newToken.token = token;
7459                    try {
7460                        token.linkToDeath(newToken, 0);
7461                        mForegroundProcesses.put(pid, newToken);
7462                        pr.forcingToForeground = token;
7463                        changed = true;
7464                    } catch (RemoteException e) {
7465                        // If the process died while doing this, we will later
7466                        // do the cleanup with the process death link.
7467                    }
7468                }
7469            }
7470
7471            if (changed) {
7472                updateOomAdjLocked();
7473            }
7474        }
7475    }
7476
7477    @Override
7478    public boolean isAppForeground(int uid) throws RemoteException {
7479        synchronized (this) {
7480            UidRecord uidRec = mActiveUids.get(uid);
7481            if (uidRec == null || uidRec.idle) {
7482                return false;
7483            }
7484            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7485        }
7486    }
7487
7488    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7489    // be guarded by permission checking.
7490    int getUidState(int uid) {
7491        synchronized (this) {
7492            UidRecord uidRec = mActiveUids.get(uid);
7493            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7494        }
7495    }
7496
7497    @Override
7498    public boolean isInMultiWindowMode(IBinder token) {
7499        final long origId = Binder.clearCallingIdentity();
7500        try {
7501            synchronized(this) {
7502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7503                if (r == null) {
7504                    return false;
7505                }
7506                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7507                return !r.task.mFullscreen;
7508            }
7509        } finally {
7510            Binder.restoreCallingIdentity(origId);
7511        }
7512    }
7513
7514    @Override
7515    public boolean isInPictureInPictureMode(IBinder token) {
7516        final long origId = Binder.clearCallingIdentity();
7517        try {
7518            synchronized(this) {
7519                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7520                if (stack == null) {
7521                    return false;
7522                }
7523                return stack.mStackId == PINNED_STACK_ID;
7524            }
7525        } finally {
7526            Binder.restoreCallingIdentity(origId);
7527        }
7528    }
7529
7530    @Override
7531    public void enterPictureInPictureMode(IBinder token) {
7532        final long origId = Binder.clearCallingIdentity();
7533        try {
7534            synchronized(this) {
7535                if (!mSupportsPictureInPicture) {
7536                    throw new IllegalStateException("enterPictureInPictureMode: "
7537                            + "Device doesn't support picture-in-picture mode.");
7538                }
7539
7540                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7541
7542                if (r == null) {
7543                    throw new IllegalStateException("enterPictureInPictureMode: "
7544                            + "Can't find activity for token=" + token);
7545                }
7546
7547                if (!r.supportsPictureInPicture()) {
7548                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7549                            + "Picture-In-Picture not supported for r=" + r);
7550                }
7551
7552                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7553                // current bounds.
7554                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7555                final Rect bounds = (pinnedStack != null)
7556                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7557
7558                mStackSupervisor.moveActivityToPinnedStackLocked(
7559                        r, "enterPictureInPictureMode", bounds);
7560            }
7561        } finally {
7562            Binder.restoreCallingIdentity(origId);
7563        }
7564    }
7565
7566    // =========================================================
7567    // PROCESS INFO
7568    // =========================================================
7569
7570    static class ProcessInfoService extends IProcessInfoService.Stub {
7571        final ActivityManagerService mActivityManagerService;
7572        ProcessInfoService(ActivityManagerService activityManagerService) {
7573            mActivityManagerService = activityManagerService;
7574        }
7575
7576        @Override
7577        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7578            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7579                    /*in*/ pids, /*out*/ states, null);
7580        }
7581
7582        @Override
7583        public void getProcessStatesAndOomScoresFromPids(
7584                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7585            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7586                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7587        }
7588    }
7589
7590    /**
7591     * For each PID in the given input array, write the current process state
7592     * for that process into the states array, or -1 to indicate that no
7593     * process with the given PID exists. If scores array is provided, write
7594     * the oom score for the process into the scores array, with INVALID_ADJ
7595     * indicating the PID doesn't exist.
7596     */
7597    public void getProcessStatesAndOomScoresForPIDs(
7598            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7599        if (scores != null) {
7600            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7601                    "getProcessStatesAndOomScoresForPIDs()");
7602        }
7603
7604        if (pids == null) {
7605            throw new NullPointerException("pids");
7606        } else if (states == null) {
7607            throw new NullPointerException("states");
7608        } else if (pids.length != states.length) {
7609            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7610        } else if (scores != null && pids.length != scores.length) {
7611            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7612        }
7613
7614        synchronized (mPidsSelfLocked) {
7615            for (int i = 0; i < pids.length; i++) {
7616                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7617                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7618                        pr.curProcState;
7619                if (scores != null) {
7620                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7621                }
7622            }
7623        }
7624    }
7625
7626    // =========================================================
7627    // PERMISSIONS
7628    // =========================================================
7629
7630    static class PermissionController extends IPermissionController.Stub {
7631        ActivityManagerService mActivityManagerService;
7632        PermissionController(ActivityManagerService activityManagerService) {
7633            mActivityManagerService = activityManagerService;
7634        }
7635
7636        @Override
7637        public boolean checkPermission(String permission, int pid, int uid) {
7638            return mActivityManagerService.checkPermission(permission, pid,
7639                    uid) == PackageManager.PERMISSION_GRANTED;
7640        }
7641
7642        @Override
7643        public String[] getPackagesForUid(int uid) {
7644            return mActivityManagerService.mContext.getPackageManager()
7645                    .getPackagesForUid(uid);
7646        }
7647
7648        @Override
7649        public boolean isRuntimePermission(String permission) {
7650            try {
7651                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7652                        .getPermissionInfo(permission, 0);
7653                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7654            } catch (NameNotFoundException nnfe) {
7655                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7656            }
7657            return false;
7658        }
7659    }
7660
7661    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7662        @Override
7663        public int checkComponentPermission(String permission, int pid, int uid,
7664                int owningUid, boolean exported) {
7665            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7666                    owningUid, exported);
7667        }
7668
7669        @Override
7670        public Object getAMSLock() {
7671            return ActivityManagerService.this;
7672        }
7673    }
7674
7675    /**
7676     * This can be called with or without the global lock held.
7677     */
7678    int checkComponentPermission(String permission, int pid, int uid,
7679            int owningUid, boolean exported) {
7680        if (pid == MY_PID) {
7681            return PackageManager.PERMISSION_GRANTED;
7682        }
7683        return ActivityManager.checkComponentPermission(permission, uid,
7684                owningUid, exported);
7685    }
7686
7687    /**
7688     * As the only public entry point for permissions checking, this method
7689     * can enforce the semantic that requesting a check on a null global
7690     * permission is automatically denied.  (Internally a null permission
7691     * string is used when calling {@link #checkComponentPermission} in cases
7692     * when only uid-based security is needed.)
7693     *
7694     * This can be called with or without the global lock held.
7695     */
7696    @Override
7697    public int checkPermission(String permission, int pid, int uid) {
7698        if (permission == null) {
7699            return PackageManager.PERMISSION_DENIED;
7700        }
7701        return checkComponentPermission(permission, pid, uid, -1, true);
7702    }
7703
7704    @Override
7705    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7706        if (permission == null) {
7707            return PackageManager.PERMISSION_DENIED;
7708        }
7709
7710        // We might be performing an operation on behalf of an indirect binder
7711        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7712        // client identity accordingly before proceeding.
7713        Identity tlsIdentity = sCallerIdentity.get();
7714        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7715            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7716                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7717            uid = tlsIdentity.uid;
7718            pid = tlsIdentity.pid;
7719        }
7720
7721        return checkComponentPermission(permission, pid, uid, -1, true);
7722    }
7723
7724    /**
7725     * Binder IPC calls go through the public entry point.
7726     * This can be called with or without the global lock held.
7727     */
7728    int checkCallingPermission(String permission) {
7729        return checkPermission(permission,
7730                Binder.getCallingPid(),
7731                UserHandle.getAppId(Binder.getCallingUid()));
7732    }
7733
7734    /**
7735     * This can be called with or without the global lock held.
7736     */
7737    void enforceCallingPermission(String permission, String func) {
7738        if (checkCallingPermission(permission)
7739                == PackageManager.PERMISSION_GRANTED) {
7740            return;
7741        }
7742
7743        String msg = "Permission Denial: " + func + " from pid="
7744                + Binder.getCallingPid()
7745                + ", uid=" + Binder.getCallingUid()
7746                + " requires " + permission;
7747        Slog.w(TAG, msg);
7748        throw new SecurityException(msg);
7749    }
7750
7751    /**
7752     * Determine if UID is holding permissions required to access {@link Uri} in
7753     * the given {@link ProviderInfo}. Final permission checking is always done
7754     * in {@link ContentProvider}.
7755     */
7756    private final boolean checkHoldingPermissionsLocked(
7757            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7758        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7759                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7760        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7761            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7762                    != PERMISSION_GRANTED) {
7763                return false;
7764            }
7765        }
7766        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7767    }
7768
7769    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7770            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7771        if (pi.applicationInfo.uid == uid) {
7772            return true;
7773        } else if (!pi.exported) {
7774            return false;
7775        }
7776
7777        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7778        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7779        try {
7780            // check if target holds top-level <provider> permissions
7781            if (!readMet && pi.readPermission != null && considerUidPermissions
7782                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7783                readMet = true;
7784            }
7785            if (!writeMet && pi.writePermission != null && considerUidPermissions
7786                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7787                writeMet = true;
7788            }
7789
7790            // track if unprotected read/write is allowed; any denied
7791            // <path-permission> below removes this ability
7792            boolean allowDefaultRead = pi.readPermission == null;
7793            boolean allowDefaultWrite = pi.writePermission == null;
7794
7795            // check if target holds any <path-permission> that match uri
7796            final PathPermission[] pps = pi.pathPermissions;
7797            if (pps != null) {
7798                final String path = grantUri.uri.getPath();
7799                int i = pps.length;
7800                while (i > 0 && (!readMet || !writeMet)) {
7801                    i--;
7802                    PathPermission pp = pps[i];
7803                    if (pp.match(path)) {
7804                        if (!readMet) {
7805                            final String pprperm = pp.getReadPermission();
7806                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7807                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7808                                    + ": match=" + pp.match(path)
7809                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7810                            if (pprperm != null) {
7811                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7812                                        == PERMISSION_GRANTED) {
7813                                    readMet = true;
7814                                } else {
7815                                    allowDefaultRead = false;
7816                                }
7817                            }
7818                        }
7819                        if (!writeMet) {
7820                            final String ppwperm = pp.getWritePermission();
7821                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7822                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7823                                    + ": match=" + pp.match(path)
7824                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7825                            if (ppwperm != null) {
7826                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7827                                        == PERMISSION_GRANTED) {
7828                                    writeMet = true;
7829                                } else {
7830                                    allowDefaultWrite = false;
7831                                }
7832                            }
7833                        }
7834                    }
7835                }
7836            }
7837
7838            // grant unprotected <provider> read/write, if not blocked by
7839            // <path-permission> above
7840            if (allowDefaultRead) readMet = true;
7841            if (allowDefaultWrite) writeMet = true;
7842
7843        } catch (RemoteException e) {
7844            return false;
7845        }
7846
7847        return readMet && writeMet;
7848    }
7849
7850    public int getAppStartMode(int uid, String packageName) {
7851        synchronized (this) {
7852            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7853        }
7854    }
7855
7856    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7857            boolean allowWhenForeground) {
7858        UidRecord uidRec = mActiveUids.get(uid);
7859        if (!mLenientBackgroundCheck) {
7860            if (!allowWhenForeground || uidRec == null
7861                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7862                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7863                        packageName) != AppOpsManager.MODE_ALLOWED) {
7864                    return ActivityManager.APP_START_MODE_DELAYED;
7865                }
7866            }
7867
7868        } else if (uidRec == null || uidRec.idle) {
7869            if (callingPid >= 0) {
7870                ProcessRecord proc;
7871                synchronized (mPidsSelfLocked) {
7872                    proc = mPidsSelfLocked.get(callingPid);
7873                }
7874                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7875                    // Whoever is instigating this is in the foreground, so we will allow it
7876                    // to go through.
7877                    return ActivityManager.APP_START_MODE_NORMAL;
7878                }
7879            }
7880            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7881                    != AppOpsManager.MODE_ALLOWED) {
7882                return ActivityManager.APP_START_MODE_DELAYED;
7883            }
7884        }
7885        return ActivityManager.APP_START_MODE_NORMAL;
7886    }
7887
7888    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7889        ProviderInfo pi = null;
7890        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7891        if (cpr != null) {
7892            pi = cpr.info;
7893        } else {
7894            try {
7895                pi = AppGlobals.getPackageManager().resolveContentProvider(
7896                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7897                        userHandle);
7898            } catch (RemoteException ex) {
7899            }
7900        }
7901        return pi;
7902    }
7903
7904    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7905        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7906        if (targetUris != null) {
7907            return targetUris.get(grantUri);
7908        }
7909        return null;
7910    }
7911
7912    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7913            String targetPkg, int targetUid, GrantUri grantUri) {
7914        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7915        if (targetUris == null) {
7916            targetUris = Maps.newArrayMap();
7917            mGrantedUriPermissions.put(targetUid, targetUris);
7918        }
7919
7920        UriPermission perm = targetUris.get(grantUri);
7921        if (perm == null) {
7922            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7923            targetUris.put(grantUri, perm);
7924        }
7925
7926        return perm;
7927    }
7928
7929    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7930            final int modeFlags) {
7931        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7932        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7933                : UriPermission.STRENGTH_OWNED;
7934
7935        // Root gets to do everything.
7936        if (uid == 0) {
7937            return true;
7938        }
7939
7940        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7941        if (perms == null) return false;
7942
7943        // First look for exact match
7944        final UriPermission exactPerm = perms.get(grantUri);
7945        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7946            return true;
7947        }
7948
7949        // No exact match, look for prefixes
7950        final int N = perms.size();
7951        for (int i = 0; i < N; i++) {
7952            final UriPermission perm = perms.valueAt(i);
7953            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7954                    && perm.getStrength(modeFlags) >= minStrength) {
7955                return true;
7956            }
7957        }
7958
7959        return false;
7960    }
7961
7962    /**
7963     * @param uri This uri must NOT contain an embedded userId.
7964     * @param userId The userId in which the uri is to be resolved.
7965     */
7966    @Override
7967    public int checkUriPermission(Uri uri, int pid, int uid,
7968            final int modeFlags, int userId, IBinder callerToken) {
7969        enforceNotIsolatedCaller("checkUriPermission");
7970
7971        // Another redirected-binder-call permissions check as in
7972        // {@link checkPermissionWithToken}.
7973        Identity tlsIdentity = sCallerIdentity.get();
7974        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7975            uid = tlsIdentity.uid;
7976            pid = tlsIdentity.pid;
7977        }
7978
7979        // Our own process gets to do everything.
7980        if (pid == MY_PID) {
7981            return PackageManager.PERMISSION_GRANTED;
7982        }
7983        synchronized (this) {
7984            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7985                    ? PackageManager.PERMISSION_GRANTED
7986                    : PackageManager.PERMISSION_DENIED;
7987        }
7988    }
7989
7990    /**
7991     * Check if the targetPkg can be granted permission to access uri by
7992     * the callingUid using the given modeFlags.  Throws a security exception
7993     * if callingUid is not allowed to do this.  Returns the uid of the target
7994     * if the URI permission grant should be performed; returns -1 if it is not
7995     * needed (for example targetPkg already has permission to access the URI).
7996     * If you already know the uid of the target, you can supply it in
7997     * lastTargetUid else set that to -1.
7998     */
7999    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8000            final int modeFlags, int lastTargetUid) {
8001        if (!Intent.isAccessUriMode(modeFlags)) {
8002            return -1;
8003        }
8004
8005        if (targetPkg != null) {
8006            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8007                    "Checking grant " + targetPkg + " permission to " + grantUri);
8008        }
8009
8010        final IPackageManager pm = AppGlobals.getPackageManager();
8011
8012        // If this is not a content: uri, we can't do anything with it.
8013        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8014            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015                    "Can't grant URI permission for non-content URI: " + grantUri);
8016            return -1;
8017        }
8018
8019        final String authority = grantUri.uri.getAuthority();
8020        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8021                MATCH_DEBUG_TRIAGED_MISSING);
8022        if (pi == null) {
8023            Slog.w(TAG, "No content provider found for permission check: " +
8024                    grantUri.uri.toSafeString());
8025            return -1;
8026        }
8027
8028        int targetUid = lastTargetUid;
8029        if (targetUid < 0 && targetPkg != null) {
8030            try {
8031                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8032                        UserHandle.getUserId(callingUid));
8033                if (targetUid < 0) {
8034                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8035                            "Can't grant URI permission no uid for: " + targetPkg);
8036                    return -1;
8037                }
8038            } catch (RemoteException ex) {
8039                return -1;
8040            }
8041        }
8042
8043        if (targetUid >= 0) {
8044            // First...  does the target actually need this permission?
8045            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8046                // No need to grant the target this permission.
8047                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8048                        "Target " + targetPkg + " already has full permission to " + grantUri);
8049                return -1;
8050            }
8051        } else {
8052            // First...  there is no target package, so can anyone access it?
8053            boolean allowed = pi.exported;
8054            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8055                if (pi.readPermission != null) {
8056                    allowed = false;
8057                }
8058            }
8059            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8060                if (pi.writePermission != null) {
8061                    allowed = false;
8062                }
8063            }
8064            if (allowed) {
8065                return -1;
8066            }
8067        }
8068
8069        /* There is a special cross user grant if:
8070         * - The target is on another user.
8071         * - Apps on the current user can access the uri without any uid permissions.
8072         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8073         * grant uri permissions.
8074         */
8075        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8076                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8077                modeFlags, false /*without considering the uid permissions*/);
8078
8079        // Second...  is the provider allowing granting of URI permissions?
8080        if (!specialCrossUserGrant) {
8081            if (!pi.grantUriPermissions) {
8082                throw new SecurityException("Provider " + pi.packageName
8083                        + "/" + pi.name
8084                        + " does not allow granting of Uri permissions (uri "
8085                        + grantUri + ")");
8086            }
8087            if (pi.uriPermissionPatterns != null) {
8088                final int N = pi.uriPermissionPatterns.length;
8089                boolean allowed = false;
8090                for (int i=0; i<N; i++) {
8091                    if (pi.uriPermissionPatterns[i] != null
8092                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8093                        allowed = true;
8094                        break;
8095                    }
8096                }
8097                if (!allowed) {
8098                    throw new SecurityException("Provider " + pi.packageName
8099                            + "/" + pi.name
8100                            + " does not allow granting of permission to path of Uri "
8101                            + grantUri);
8102                }
8103            }
8104        }
8105
8106        // Third...  does the caller itself have permission to access
8107        // this uri?
8108        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8109            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8110                // Require they hold a strong enough Uri permission
8111                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8112                    throw new SecurityException("Uid " + callingUid
8113                            + " does not have permission to uri " + grantUri);
8114                }
8115            }
8116        }
8117        return targetUid;
8118    }
8119
8120    /**
8121     * @param uri This uri must NOT contain an embedded userId.
8122     * @param userId The userId in which the uri is to be resolved.
8123     */
8124    @Override
8125    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8126            final int modeFlags, int userId) {
8127        enforceNotIsolatedCaller("checkGrantUriPermission");
8128        synchronized(this) {
8129            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8130                    new GrantUri(userId, uri, false), modeFlags, -1);
8131        }
8132    }
8133
8134    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8135            final int modeFlags, UriPermissionOwner owner) {
8136        if (!Intent.isAccessUriMode(modeFlags)) {
8137            return;
8138        }
8139
8140        // So here we are: the caller has the assumed permission
8141        // to the uri, and the target doesn't.  Let's now give this to
8142        // the target.
8143
8144        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8145                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8146
8147        final String authority = grantUri.uri.getAuthority();
8148        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8149                MATCH_DEBUG_TRIAGED_MISSING);
8150        if (pi == null) {
8151            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8152            return;
8153        }
8154
8155        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8156            grantUri.prefix = true;
8157        }
8158        final UriPermission perm = findOrCreateUriPermissionLocked(
8159                pi.packageName, targetPkg, targetUid, grantUri);
8160        perm.grantModes(modeFlags, owner);
8161    }
8162
8163    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8164            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8165        if (targetPkg == null) {
8166            throw new NullPointerException("targetPkg");
8167        }
8168        int targetUid;
8169        final IPackageManager pm = AppGlobals.getPackageManager();
8170        try {
8171            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8172        } catch (RemoteException ex) {
8173            return;
8174        }
8175
8176        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8177                targetUid);
8178        if (targetUid < 0) {
8179            return;
8180        }
8181
8182        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8183                owner);
8184    }
8185
8186    static class NeededUriGrants extends ArrayList<GrantUri> {
8187        final String targetPkg;
8188        final int targetUid;
8189        final int flags;
8190
8191        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8192            this.targetPkg = targetPkg;
8193            this.targetUid = targetUid;
8194            this.flags = flags;
8195        }
8196    }
8197
8198    /**
8199     * Like checkGrantUriPermissionLocked, but takes an Intent.
8200     */
8201    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8202            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8203        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8204                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8205                + " clip=" + (intent != null ? intent.getClipData() : null)
8206                + " from " + intent + "; flags=0x"
8207                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8208
8209        if (targetPkg == null) {
8210            throw new NullPointerException("targetPkg");
8211        }
8212
8213        if (intent == null) {
8214            return null;
8215        }
8216        Uri data = intent.getData();
8217        ClipData clip = intent.getClipData();
8218        if (data == null && clip == null) {
8219            return null;
8220        }
8221        // Default userId for uris in the intent (if they don't specify it themselves)
8222        int contentUserHint = intent.getContentUserHint();
8223        if (contentUserHint == UserHandle.USER_CURRENT) {
8224            contentUserHint = UserHandle.getUserId(callingUid);
8225        }
8226        final IPackageManager pm = AppGlobals.getPackageManager();
8227        int targetUid;
8228        if (needed != null) {
8229            targetUid = needed.targetUid;
8230        } else {
8231            try {
8232                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8233                        targetUserId);
8234            } catch (RemoteException ex) {
8235                return null;
8236            }
8237            if (targetUid < 0) {
8238                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8239                        "Can't grant URI permission no uid for: " + targetPkg
8240                        + " on user " + targetUserId);
8241                return null;
8242            }
8243        }
8244        if (data != null) {
8245            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8246            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8247                    targetUid);
8248            if (targetUid > 0) {
8249                if (needed == null) {
8250                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8251                }
8252                needed.add(grantUri);
8253            }
8254        }
8255        if (clip != null) {
8256            for (int i=0; i<clip.getItemCount(); i++) {
8257                Uri uri = clip.getItemAt(i).getUri();
8258                if (uri != null) {
8259                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8260                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8261                            targetUid);
8262                    if (targetUid > 0) {
8263                        if (needed == null) {
8264                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8265                        }
8266                        needed.add(grantUri);
8267                    }
8268                } else {
8269                    Intent clipIntent = clip.getItemAt(i).getIntent();
8270                    if (clipIntent != null) {
8271                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8272                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8273                        if (newNeeded != null) {
8274                            needed = newNeeded;
8275                        }
8276                    }
8277                }
8278            }
8279        }
8280
8281        return needed;
8282    }
8283
8284    /**
8285     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8286     */
8287    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8288            UriPermissionOwner owner) {
8289        if (needed != null) {
8290            for (int i=0; i<needed.size(); i++) {
8291                GrantUri grantUri = needed.get(i);
8292                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8293                        grantUri, needed.flags, owner);
8294            }
8295        }
8296    }
8297
8298    void grantUriPermissionFromIntentLocked(int callingUid,
8299            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8300        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8301                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8302        if (needed == null) {
8303            return;
8304        }
8305
8306        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8307    }
8308
8309    /**
8310     * @param uri This uri must NOT contain an embedded userId.
8311     * @param userId The userId in which the uri is to be resolved.
8312     */
8313    @Override
8314    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8315            final int modeFlags, int userId) {
8316        enforceNotIsolatedCaller("grantUriPermission");
8317        GrantUri grantUri = new GrantUri(userId, uri, false);
8318        synchronized(this) {
8319            final ProcessRecord r = getRecordForAppLocked(caller);
8320            if (r == null) {
8321                throw new SecurityException("Unable to find app for caller "
8322                        + caller
8323                        + " when granting permission to uri " + grantUri);
8324            }
8325            if (targetPkg == null) {
8326                throw new IllegalArgumentException("null target");
8327            }
8328            if (grantUri == null) {
8329                throw new IllegalArgumentException("null uri");
8330            }
8331
8332            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8333                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8334                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8335                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8336
8337            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8338                    UserHandle.getUserId(r.uid));
8339        }
8340    }
8341
8342    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8343        if (perm.modeFlags == 0) {
8344            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8345                    perm.targetUid);
8346            if (perms != null) {
8347                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8349
8350                perms.remove(perm.uri);
8351                if (perms.isEmpty()) {
8352                    mGrantedUriPermissions.remove(perm.targetUid);
8353                }
8354            }
8355        }
8356    }
8357
8358    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8359        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8360                "Revoking all granted permissions to " + grantUri);
8361
8362        final IPackageManager pm = AppGlobals.getPackageManager();
8363        final String authority = grantUri.uri.getAuthority();
8364        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8365                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8366        if (pi == null) {
8367            Slog.w(TAG, "No content provider found for permission revoke: "
8368                    + grantUri.toSafeString());
8369            return;
8370        }
8371
8372        // Does the caller have this permission on the URI?
8373        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8374            // If they don't have direct access to the URI, then revoke any
8375            // ownerless URI permissions that have been granted to them.
8376            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8377            if (perms != null) {
8378                boolean persistChanged = false;
8379                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8380                    final UriPermission perm = it.next();
8381                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8382                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8383                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8384                                "Revoking non-owned " + perm.targetUid
8385                                + " permission to " + perm.uri);
8386                        persistChanged |= perm.revokeModes(
8387                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8388                        if (perm.modeFlags == 0) {
8389                            it.remove();
8390                        }
8391                    }
8392                }
8393                if (perms.isEmpty()) {
8394                    mGrantedUriPermissions.remove(callingUid);
8395                }
8396                if (persistChanged) {
8397                    schedulePersistUriGrants();
8398                }
8399            }
8400            return;
8401        }
8402
8403        boolean persistChanged = false;
8404
8405        // Go through all of the permissions and remove any that match.
8406        int N = mGrantedUriPermissions.size();
8407        for (int i = 0; i < N; i++) {
8408            final int targetUid = mGrantedUriPermissions.keyAt(i);
8409            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8410
8411            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8412                final UriPermission perm = it.next();
8413                if (perm.uri.sourceUserId == grantUri.sourceUserId
8414                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8415                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8416                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8417                    persistChanged |= perm.revokeModes(
8418                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8419                    if (perm.modeFlags == 0) {
8420                        it.remove();
8421                    }
8422                }
8423            }
8424
8425            if (perms.isEmpty()) {
8426                mGrantedUriPermissions.remove(targetUid);
8427                N--;
8428                i--;
8429            }
8430        }
8431
8432        if (persistChanged) {
8433            schedulePersistUriGrants();
8434        }
8435    }
8436
8437    /**
8438     * @param uri This uri must NOT contain an embedded userId.
8439     * @param userId The userId in which the uri is to be resolved.
8440     */
8441    @Override
8442    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8443            int userId) {
8444        enforceNotIsolatedCaller("revokeUriPermission");
8445        synchronized(this) {
8446            final ProcessRecord r = getRecordForAppLocked(caller);
8447            if (r == null) {
8448                throw new SecurityException("Unable to find app for caller "
8449                        + caller
8450                        + " when revoking permission to uri " + uri);
8451            }
8452            if (uri == null) {
8453                Slog.w(TAG, "revokeUriPermission: null uri");
8454                return;
8455            }
8456
8457            if (!Intent.isAccessUriMode(modeFlags)) {
8458                return;
8459            }
8460
8461            final String authority = uri.getAuthority();
8462            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8463                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8464            if (pi == null) {
8465                Slog.w(TAG, "No content provider found for permission revoke: "
8466                        + uri.toSafeString());
8467                return;
8468            }
8469
8470            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8471        }
8472    }
8473
8474    /**
8475     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8476     * given package.
8477     *
8478     * @param packageName Package name to match, or {@code null} to apply to all
8479     *            packages.
8480     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8481     *            to all users.
8482     * @param persistable If persistable grants should be removed.
8483     */
8484    private void removeUriPermissionsForPackageLocked(
8485            String packageName, int userHandle, boolean persistable) {
8486        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8487            throw new IllegalArgumentException("Must narrow by either package or user");
8488        }
8489
8490        boolean persistChanged = false;
8491
8492        int N = mGrantedUriPermissions.size();
8493        for (int i = 0; i < N; i++) {
8494            final int targetUid = mGrantedUriPermissions.keyAt(i);
8495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8496
8497            // Only inspect grants matching user
8498            if (userHandle == UserHandle.USER_ALL
8499                    || userHandle == UserHandle.getUserId(targetUid)) {
8500                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8501                    final UriPermission perm = it.next();
8502
8503                    // Only inspect grants matching package
8504                    if (packageName == null || perm.sourcePkg.equals(packageName)
8505                            || perm.targetPkg.equals(packageName)) {
8506                        persistChanged |= perm.revokeModes(persistable
8507                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8508
8509                        // Only remove when no modes remain; any persisted grants
8510                        // will keep this alive.
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
8525        if (persistChanged) {
8526            schedulePersistUriGrants();
8527        }
8528    }
8529
8530    @Override
8531    public IBinder newUriPermissionOwner(String name) {
8532        enforceNotIsolatedCaller("newUriPermissionOwner");
8533        synchronized(this) {
8534            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8535            return owner.getExternalTokenLocked();
8536        }
8537    }
8538
8539    @Override
8540    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8541        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8542        synchronized(this) {
8543            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8544            if (r == null) {
8545                throw new IllegalArgumentException("Activity does not exist; token="
8546                        + activityToken);
8547            }
8548            return r.getUriPermissionsLocked().getExternalTokenLocked();
8549        }
8550    }
8551    /**
8552     * @param uri This uri must NOT contain an embedded userId.
8553     * @param sourceUserId The userId in which the uri is to be resolved.
8554     * @param targetUserId The userId of the app that receives the grant.
8555     */
8556    @Override
8557    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8558            final int modeFlags, int sourceUserId, int targetUserId) {
8559        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8560                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8561                "grantUriPermissionFromOwner", null);
8562        synchronized(this) {
8563            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8564            if (owner == null) {
8565                throw new IllegalArgumentException("Unknown owner: " + token);
8566            }
8567            if (fromUid != Binder.getCallingUid()) {
8568                if (Binder.getCallingUid() != Process.myUid()) {
8569                    // Only system code can grant URI permissions on behalf
8570                    // of other users.
8571                    throw new SecurityException("nice try");
8572                }
8573            }
8574            if (targetPkg == null) {
8575                throw new IllegalArgumentException("null target");
8576            }
8577            if (uri == null) {
8578                throw new IllegalArgumentException("null uri");
8579            }
8580
8581            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8582                    modeFlags, owner, targetUserId);
8583        }
8584    }
8585
8586    /**
8587     * @param uri This uri must NOT contain an embedded userId.
8588     * @param userId The userId in which the uri is to be resolved.
8589     */
8590    @Override
8591    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8592        synchronized(this) {
8593            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8594            if (owner == null) {
8595                throw new IllegalArgumentException("Unknown owner: " + token);
8596            }
8597
8598            if (uri == null) {
8599                owner.removeUriPermissionsLocked(mode);
8600            } else {
8601                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8602            }
8603        }
8604    }
8605
8606    private void schedulePersistUriGrants() {
8607        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8608            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8609                    10 * DateUtils.SECOND_IN_MILLIS);
8610        }
8611    }
8612
8613    private void writeGrantedUriPermissions() {
8614        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8615
8616        // Snapshot permissions so we can persist without lock
8617        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8618        synchronized (this) {
8619            final int size = mGrantedUriPermissions.size();
8620            for (int i = 0; i < size; i++) {
8621                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8622                for (UriPermission perm : perms.values()) {
8623                    if (perm.persistedModeFlags != 0) {
8624                        persist.add(perm.snapshot());
8625                    }
8626                }
8627            }
8628        }
8629
8630        FileOutputStream fos = null;
8631        try {
8632            fos = mGrantFile.startWrite();
8633
8634            XmlSerializer out = new FastXmlSerializer();
8635            out.setOutput(fos, StandardCharsets.UTF_8.name());
8636            out.startDocument(null, true);
8637            out.startTag(null, TAG_URI_GRANTS);
8638            for (UriPermission.Snapshot perm : persist) {
8639                out.startTag(null, TAG_URI_GRANT);
8640                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8641                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8642                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8643                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8644                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8645                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8646                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8647                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8648                out.endTag(null, TAG_URI_GRANT);
8649            }
8650            out.endTag(null, TAG_URI_GRANTS);
8651            out.endDocument();
8652
8653            mGrantFile.finishWrite(fos);
8654        } catch (IOException e) {
8655            if (fos != null) {
8656                mGrantFile.failWrite(fos);
8657            }
8658        }
8659    }
8660
8661    private void readGrantedUriPermissionsLocked() {
8662        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8663
8664        final long now = System.currentTimeMillis();
8665
8666        FileInputStream fis = null;
8667        try {
8668            fis = mGrantFile.openRead();
8669            final XmlPullParser in = Xml.newPullParser();
8670            in.setInput(fis, StandardCharsets.UTF_8.name());
8671
8672            int type;
8673            while ((type = in.next()) != END_DOCUMENT) {
8674                final String tag = in.getName();
8675                if (type == START_TAG) {
8676                    if (TAG_URI_GRANT.equals(tag)) {
8677                        final int sourceUserId;
8678                        final int targetUserId;
8679                        final int userHandle = readIntAttribute(in,
8680                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8681                        if (userHandle != UserHandle.USER_NULL) {
8682                            // For backwards compatibility.
8683                            sourceUserId = userHandle;
8684                            targetUserId = userHandle;
8685                        } else {
8686                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8687                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8688                        }
8689                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8690                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8691                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8692                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8693                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8694                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8695
8696                        // Sanity check that provider still belongs to source package
8697                        // Both direct boot aware and unaware packages are fine as we
8698                        // will do filtering at query time to avoid multiple parsing.
8699                        final ProviderInfo pi = getProviderInfoLocked(
8700                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8701                                        | MATCH_DIRECT_BOOT_UNAWARE);
8702                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8703                            int targetUid = -1;
8704                            try {
8705                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8706                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8707                            } catch (RemoteException e) {
8708                            }
8709                            if (targetUid != -1) {
8710                                final UriPermission perm = findOrCreateUriPermissionLocked(
8711                                        sourcePkg, targetPkg, targetUid,
8712                                        new GrantUri(sourceUserId, uri, prefix));
8713                                perm.initPersistedModes(modeFlags, createdTime);
8714                            }
8715                        } else {
8716                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8717                                    + " but instead found " + pi);
8718                        }
8719                    }
8720                }
8721            }
8722        } catch (FileNotFoundException e) {
8723            // Missing grants is okay
8724        } catch (IOException e) {
8725            Slog.wtf(TAG, "Failed reading Uri grants", e);
8726        } catch (XmlPullParserException e) {
8727            Slog.wtf(TAG, "Failed reading Uri grants", e);
8728        } finally {
8729            IoUtils.closeQuietly(fis);
8730        }
8731    }
8732
8733    /**
8734     * @param uri This uri must NOT contain an embedded userId.
8735     * @param userId The userId in which the uri is to be resolved.
8736     */
8737    @Override
8738    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8739        enforceNotIsolatedCaller("takePersistableUriPermission");
8740
8741        Preconditions.checkFlagsArgument(modeFlags,
8742                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8743
8744        synchronized (this) {
8745            final int callingUid = Binder.getCallingUid();
8746            boolean persistChanged = false;
8747            GrantUri grantUri = new GrantUri(userId, uri, false);
8748
8749            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8750                    new GrantUri(userId, uri, false));
8751            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8752                    new GrantUri(userId, uri, true));
8753
8754            final boolean exactValid = (exactPerm != null)
8755                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8756            final boolean prefixValid = (prefixPerm != null)
8757                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8758
8759            if (!(exactValid || prefixValid)) {
8760                throw new SecurityException("No persistable permission grants found for UID "
8761                        + callingUid + " and Uri " + grantUri.toSafeString());
8762            }
8763
8764            if (exactValid) {
8765                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8766            }
8767            if (prefixValid) {
8768                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8769            }
8770
8771            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8772
8773            if (persistChanged) {
8774                schedulePersistUriGrants();
8775            }
8776        }
8777    }
8778
8779    /**
8780     * @param uri This uri must NOT contain an embedded userId.
8781     * @param userId The userId in which the uri is to be resolved.
8782     */
8783    @Override
8784    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8785        enforceNotIsolatedCaller("releasePersistableUriPermission");
8786
8787        Preconditions.checkFlagsArgument(modeFlags,
8788                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8789
8790        synchronized (this) {
8791            final int callingUid = Binder.getCallingUid();
8792            boolean persistChanged = false;
8793
8794            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8795                    new GrantUri(userId, uri, false));
8796            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8797                    new GrantUri(userId, uri, true));
8798            if (exactPerm == null && prefixPerm == null) {
8799                throw new SecurityException("No permission grants found for UID " + callingUid
8800                        + " and Uri " + uri.toSafeString());
8801            }
8802
8803            if (exactPerm != null) {
8804                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8805                removeUriPermissionIfNeededLocked(exactPerm);
8806            }
8807            if (prefixPerm != null) {
8808                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8809                removeUriPermissionIfNeededLocked(prefixPerm);
8810            }
8811
8812            if (persistChanged) {
8813                schedulePersistUriGrants();
8814            }
8815        }
8816    }
8817
8818    /**
8819     * Prune any older {@link UriPermission} for the given UID until outstanding
8820     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8821     *
8822     * @return if any mutations occured that require persisting.
8823     */
8824    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8825        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8826        if (perms == null) return false;
8827        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8828
8829        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8830        for (UriPermission perm : perms.values()) {
8831            if (perm.persistedModeFlags != 0) {
8832                persisted.add(perm);
8833            }
8834        }
8835
8836        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8837        if (trimCount <= 0) return false;
8838
8839        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8840        for (int i = 0; i < trimCount; i++) {
8841            final UriPermission perm = persisted.get(i);
8842
8843            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                    "Trimming grant created at " + perm.persistedCreateTime);
8845
8846            perm.releasePersistableModes(~0);
8847            removeUriPermissionIfNeededLocked(perm);
8848        }
8849
8850        return true;
8851    }
8852
8853    @Override
8854    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8855            String packageName, boolean incoming) {
8856        enforceNotIsolatedCaller("getPersistedUriPermissions");
8857        Preconditions.checkNotNull(packageName, "packageName");
8858
8859        final int callingUid = Binder.getCallingUid();
8860        final int callingUserId = UserHandle.getUserId(callingUid);
8861        final IPackageManager pm = AppGlobals.getPackageManager();
8862        try {
8863            final int packageUid = pm.getPackageUid(packageName,
8864                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8865            if (packageUid != callingUid) {
8866                throw new SecurityException(
8867                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8868            }
8869        } catch (RemoteException e) {
8870            throw new SecurityException("Failed to verify package name ownership");
8871        }
8872
8873        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8874        synchronized (this) {
8875            if (incoming) {
8876                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8877                        callingUid);
8878                if (perms == null) {
8879                    Slog.w(TAG, "No permission grants found for " + packageName);
8880                } else {
8881                    for (UriPermission perm : perms.values()) {
8882                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8883                            result.add(perm.buildPersistedPublicApiObject());
8884                        }
8885                    }
8886                }
8887            } else {
8888                final int size = mGrantedUriPermissions.size();
8889                for (int i = 0; i < size; i++) {
8890                    final ArrayMap<GrantUri, UriPermission> perms =
8891                            mGrantedUriPermissions.valueAt(i);
8892                    for (UriPermission perm : perms.values()) {
8893                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8894                            result.add(perm.buildPersistedPublicApiObject());
8895                        }
8896                    }
8897                }
8898            }
8899        }
8900        return new ParceledListSlice<android.content.UriPermission>(result);
8901    }
8902
8903    @Override
8904    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8905            String packageName, int userId) {
8906        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8907                "getGrantedUriPermissions");
8908
8909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8910        synchronized (this) {
8911            final int size = mGrantedUriPermissions.size();
8912            for (int i = 0; i < size; i++) {
8913                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8914                for (UriPermission perm : perms.values()) {
8915                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8916                            && perm.persistedModeFlags != 0) {
8917                        result.add(perm.buildPersistedPublicApiObject());
8918                    }
8919                }
8920            }
8921        }
8922        return new ParceledListSlice<android.content.UriPermission>(result);
8923    }
8924
8925    @Override
8926    public void clearGrantedUriPermissions(String packageName, int userId) {
8927        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8928                "clearGrantedUriPermissions");
8929        removeUriPermissionsForPackageLocked(packageName, userId, true);
8930    }
8931
8932    @Override
8933    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8934        synchronized (this) {
8935            ProcessRecord app =
8936                who != null ? getRecordForAppLocked(who) : null;
8937            if (app == null) return;
8938
8939            Message msg = Message.obtain();
8940            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8941            msg.obj = app;
8942            msg.arg1 = waiting ? 1 : 0;
8943            mUiHandler.sendMessage(msg);
8944        }
8945    }
8946
8947    @Override
8948    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8949        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8950        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8951        outInfo.availMem = Process.getFreeMemory();
8952        outInfo.totalMem = Process.getTotalMemory();
8953        outInfo.threshold = homeAppMem;
8954        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8955        outInfo.hiddenAppThreshold = cachedAppMem;
8956        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8957                ProcessList.SERVICE_ADJ);
8958        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8959                ProcessList.VISIBLE_APP_ADJ);
8960        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8961                ProcessList.FOREGROUND_APP_ADJ);
8962    }
8963
8964    // =========================================================
8965    // TASK MANAGEMENT
8966    // =========================================================
8967
8968    @Override
8969    public List<IAppTask> getAppTasks(String callingPackage) {
8970        int callingUid = Binder.getCallingUid();
8971        long ident = Binder.clearCallingIdentity();
8972
8973        synchronized(this) {
8974            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8975            try {
8976                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8977
8978                final int N = mRecentTasks.size();
8979                for (int i = 0; i < N; i++) {
8980                    TaskRecord tr = mRecentTasks.get(i);
8981                    // Skip tasks that do not match the caller.  We don't need to verify
8982                    // callingPackage, because we are also limiting to callingUid and know
8983                    // that will limit to the correct security sandbox.
8984                    if (tr.effectiveUid != callingUid) {
8985                        continue;
8986                    }
8987                    Intent intent = tr.getBaseIntent();
8988                    if (intent == null ||
8989                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8990                        continue;
8991                    }
8992                    ActivityManager.RecentTaskInfo taskInfo =
8993                            createRecentTaskInfoFromTaskRecord(tr);
8994                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8995                    list.add(taskImpl);
8996                }
8997            } finally {
8998                Binder.restoreCallingIdentity(ident);
8999            }
9000            return list;
9001        }
9002    }
9003
9004    @Override
9005    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9006        final int callingUid = Binder.getCallingUid();
9007        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9008
9009        synchronized(this) {
9010            if (DEBUG_ALL) Slog.v(
9011                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9012
9013            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9014                    callingUid);
9015
9016            // TODO: Improve with MRU list from all ActivityStacks.
9017            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9018        }
9019
9020        return list;
9021    }
9022
9023    /**
9024     * Creates a new RecentTaskInfo from a TaskRecord.
9025     */
9026    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9027        // Update the task description to reflect any changes in the task stack
9028        tr.updateTaskDescription();
9029
9030        // Compose the recent task info
9031        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9032        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9033        rti.persistentId = tr.taskId;
9034        rti.baseIntent = new Intent(tr.getBaseIntent());
9035        rti.origActivity = tr.origActivity;
9036        rti.realActivity = tr.realActivity;
9037        rti.description = tr.lastDescription;
9038        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9039        rti.userId = tr.userId;
9040        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9041        rti.firstActiveTime = tr.firstActiveTime;
9042        rti.lastActiveTime = tr.lastActiveTime;
9043        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9044        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9045        rti.numActivities = 0;
9046        if (tr.mBounds != null) {
9047            rti.bounds = new Rect(tr.mBounds);
9048        }
9049        rti.isDockable = tr.canGoInDockedStack();
9050        rti.resizeMode = tr.mResizeMode;
9051
9052        ActivityRecord base = null;
9053        ActivityRecord top = null;
9054        ActivityRecord tmp;
9055
9056        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9057            tmp = tr.mActivities.get(i);
9058            if (tmp.finishing) {
9059                continue;
9060            }
9061            base = tmp;
9062            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9063                top = base;
9064            }
9065            rti.numActivities++;
9066        }
9067
9068        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9069        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9070
9071        return rti;
9072    }
9073
9074    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9075        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9076                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9077        if (!allowed) {
9078            if (checkPermission(android.Manifest.permission.GET_TASKS,
9079                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9080                // Temporary compatibility: some existing apps on the system image may
9081                // still be requesting the old permission and not switched to the new
9082                // one; if so, we'll still allow them full access.  This means we need
9083                // to see if they are holding the old permission and are a system app.
9084                try {
9085                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9086                        allowed = true;
9087                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9088                                + " is using old GET_TASKS but privileged; allowing");
9089                    }
9090                } catch (RemoteException e) {
9091                }
9092            }
9093        }
9094        if (!allowed) {
9095            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9096                    + " does not hold REAL_GET_TASKS; limiting output");
9097        }
9098        return allowed;
9099    }
9100
9101    @Override
9102    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9103            int userId) {
9104        final int callingUid = Binder.getCallingUid();
9105        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9106                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9107
9108        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9109        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9110        synchronized (this) {
9111            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9112                    callingUid);
9113            final boolean detailed = checkCallingPermission(
9114                    android.Manifest.permission.GET_DETAILED_TASKS)
9115                    == PackageManager.PERMISSION_GRANTED;
9116
9117            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9118                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9119                return ParceledListSlice.emptyList();
9120            }
9121            mRecentTasks.loadUserRecentsLocked(userId);
9122
9123            final int recentsCount = mRecentTasks.size();
9124            ArrayList<ActivityManager.RecentTaskInfo> res =
9125                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9126
9127            final Set<Integer> includedUsers;
9128            if (includeProfiles) {
9129                includedUsers = mUserController.getProfileIds(userId);
9130            } else {
9131                includedUsers = new HashSet<>();
9132            }
9133            includedUsers.add(Integer.valueOf(userId));
9134
9135            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9136                TaskRecord tr = mRecentTasks.get(i);
9137                // Only add calling user or related users recent tasks
9138                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9139                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9140                    continue;
9141                }
9142
9143                if (tr.realActivitySuspended) {
9144                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9145                    continue;
9146                }
9147
9148                // Return the entry if desired by the caller.  We always return
9149                // the first entry, because callers always expect this to be the
9150                // foreground app.  We may filter others if the caller has
9151                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9152                // we should exclude the entry.
9153
9154                if (i == 0
9155                        || withExcluded
9156                        || (tr.intent == null)
9157                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9158                                == 0)) {
9159                    if (!allowed) {
9160                        // If the caller doesn't have the GET_TASKS permission, then only
9161                        // allow them to see a small subset of tasks -- their own and home.
9162                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9163                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9164                            continue;
9165                        }
9166                    }
9167                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9168                        if (tr.stack != null && tr.stack.isHomeStack()) {
9169                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                    "Skipping, home stack task: " + tr);
9171                            continue;
9172                        }
9173                    }
9174                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9175                        final ActivityStack stack = tr.stack;
9176                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9177                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9178                                    "Skipping, top task in docked stack: " + tr);
9179                            continue;
9180                        }
9181                    }
9182                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9183                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9184                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9185                                    "Skipping, pinned stack task: " + tr);
9186                            continue;
9187                        }
9188                    }
9189                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9190                        // Don't include auto remove tasks that are finished or finishing.
9191                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9192                                "Skipping, auto-remove without activity: " + tr);
9193                        continue;
9194                    }
9195                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9196                            && !tr.isAvailable) {
9197                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9198                                "Skipping, unavail real act: " + tr);
9199                        continue;
9200                    }
9201
9202                    if (!tr.mUserSetupComplete) {
9203                        // Don't include task launched while user is not done setting-up.
9204                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9205                                "Skipping, user setup not complete: " + tr);
9206                        continue;
9207                    }
9208
9209                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9210                    if (!detailed) {
9211                        rti.baseIntent.replaceExtras((Bundle)null);
9212                    }
9213
9214                    res.add(rti);
9215                    maxNum--;
9216                }
9217            }
9218            return new ParceledListSlice<>(res);
9219        }
9220    }
9221
9222    @Override
9223    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9224        synchronized (this) {
9225            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9226                    "getTaskThumbnail()");
9227            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9228                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9229            if (tr != null) {
9230                return tr.getTaskThumbnailLocked();
9231            }
9232        }
9233        return null;
9234    }
9235
9236    @Override
9237    public int addAppTask(IBinder activityToken, Intent intent,
9238            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9239        final int callingUid = Binder.getCallingUid();
9240        final long callingIdent = Binder.clearCallingIdentity();
9241
9242        try {
9243            synchronized (this) {
9244                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9245                if (r == null) {
9246                    throw new IllegalArgumentException("Activity does not exist; token="
9247                            + activityToken);
9248                }
9249                ComponentName comp = intent.getComponent();
9250                if (comp == null) {
9251                    throw new IllegalArgumentException("Intent " + intent
9252                            + " must specify explicit component");
9253                }
9254                if (thumbnail.getWidth() != mThumbnailWidth
9255                        || thumbnail.getHeight() != mThumbnailHeight) {
9256                    throw new IllegalArgumentException("Bad thumbnail size: got "
9257                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9258                            + mThumbnailWidth + "x" + mThumbnailHeight);
9259                }
9260                if (intent.getSelector() != null) {
9261                    intent.setSelector(null);
9262                }
9263                if (intent.getSourceBounds() != null) {
9264                    intent.setSourceBounds(null);
9265                }
9266                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9267                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9268                        // The caller has added this as an auto-remove task...  that makes no
9269                        // sense, so turn off auto-remove.
9270                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9271                    }
9272                }
9273                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9274                    mLastAddedTaskActivity = null;
9275                }
9276                ActivityInfo ainfo = mLastAddedTaskActivity;
9277                if (ainfo == null) {
9278                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9279                            comp, 0, UserHandle.getUserId(callingUid));
9280                    if (ainfo.applicationInfo.uid != callingUid) {
9281                        throw new SecurityException(
9282                                "Can't add task for another application: target uid="
9283                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9284                    }
9285                }
9286
9287                // Use the full screen as the context for the task thumbnail
9288                final Point displaySize = new Point();
9289                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9290                r.task.stack.getDisplaySize(displaySize);
9291                thumbnailInfo.taskWidth = displaySize.x;
9292                thumbnailInfo.taskHeight = displaySize.y;
9293                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9294
9295                TaskRecord task = new TaskRecord(this,
9296                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9297                        ainfo, intent, description, thumbnailInfo);
9298
9299                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9300                if (trimIdx >= 0) {
9301                    // If this would have caused a trim, then we'll abort because that
9302                    // means it would be added at the end of the list but then just removed.
9303                    return INVALID_TASK_ID;
9304                }
9305
9306                final int N = mRecentTasks.size();
9307                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9308                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9309                    tr.removedFromRecents();
9310                }
9311
9312                task.inRecents = true;
9313                mRecentTasks.add(task);
9314                r.task.stack.addTask(task, false, "addAppTask");
9315
9316                task.setLastThumbnailLocked(thumbnail);
9317                task.freeLastThumbnail();
9318
9319                return task.taskId;
9320            }
9321        } finally {
9322            Binder.restoreCallingIdentity(callingIdent);
9323        }
9324    }
9325
9326    @Override
9327    public Point getAppTaskThumbnailSize() {
9328        synchronized (this) {
9329            return new Point(mThumbnailWidth,  mThumbnailHeight);
9330        }
9331    }
9332
9333    @Override
9334    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9335        synchronized (this) {
9336            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9337            if (r != null) {
9338                r.setTaskDescription(td);
9339                r.task.updateTaskDescription();
9340            }
9341        }
9342    }
9343
9344    @Override
9345    public void setTaskResizeable(int taskId, int resizeableMode) {
9346        synchronized (this) {
9347            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9348                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9349            if (task == null) {
9350                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9351                return;
9352            }
9353            if (task.mResizeMode != resizeableMode) {
9354                task.mResizeMode = resizeableMode;
9355                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9356                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9357                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9358            }
9359        }
9360    }
9361
9362    @Override
9363    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9364        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9365        long ident = Binder.clearCallingIdentity();
9366        try {
9367            synchronized (this) {
9368                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9369                if (task == null) {
9370                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9371                    return;
9372                }
9373                int stackId = task.stack.mStackId;
9374                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9375                // in crop windows resize mode or if the task size is affected by the docked stack
9376                // changing size. No need to update configuration.
9377                if (bounds != null && task.inCropWindowsResizeMode()
9378                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9379                    mWindowManager.scrollTask(task.taskId, bounds);
9380                    return;
9381                }
9382
9383                // Place the task in the right stack if it isn't there already based on
9384                // the requested bounds.
9385                // The stack transition logic is:
9386                // - a null bounds on a freeform task moves that task to fullscreen
9387                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9388                //   that task to freeform
9389                // - otherwise the task is not moved
9390                if (!StackId.isTaskResizeAllowed(stackId)) {
9391                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9392                }
9393                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9394                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9395                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9396                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9397                }
9398                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9399                if (stackId != task.stack.mStackId) {
9400                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9401                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9402                    preserveWindow = false;
9403                }
9404
9405                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9406                        false /* deferResume */);
9407            }
9408        } finally {
9409            Binder.restoreCallingIdentity(ident);
9410        }
9411    }
9412
9413    @Override
9414    public Rect getTaskBounds(int taskId) {
9415        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9416        long ident = Binder.clearCallingIdentity();
9417        Rect rect = new Rect();
9418        try {
9419            synchronized (this) {
9420                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9421                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9422                if (task == null) {
9423                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9424                    return rect;
9425                }
9426                if (task.stack != null) {
9427                    // Return the bounds from window manager since it will be adjusted for various
9428                    // things like the presense of a docked stack for tasks that aren't resizeable.
9429                    mWindowManager.getTaskBounds(task.taskId, rect);
9430                } else {
9431                    // Task isn't in window manager yet since it isn't associated with a stack.
9432                    // Return the persist value from activity manager
9433                    if (task.mBounds != null) {
9434                        rect.set(task.mBounds);
9435                    } else if (task.mLastNonFullscreenBounds != null) {
9436                        rect.set(task.mLastNonFullscreenBounds);
9437                    }
9438                }
9439            }
9440        } finally {
9441            Binder.restoreCallingIdentity(ident);
9442        }
9443        return rect;
9444    }
9445
9446    @Override
9447    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9448        if (userId != UserHandle.getCallingUserId()) {
9449            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9450                    "getTaskDescriptionIcon");
9451        }
9452        final File passedIconFile = new File(filePath);
9453        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9454                passedIconFile.getName());
9455        if (!legitIconFile.getPath().equals(filePath)
9456                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9457            throw new IllegalArgumentException("Bad file path: " + filePath
9458                    + " passed for userId " + userId);
9459        }
9460        return mRecentTasks.getTaskDescriptionIcon(filePath);
9461    }
9462
9463    @Override
9464    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9465            throws RemoteException {
9466        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9467                opts.getCustomInPlaceResId() == 0) {
9468            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9469                    "with valid animation");
9470        }
9471        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9472        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9473                opts.getCustomInPlaceResId());
9474        mWindowManager.executeAppTransition();
9475    }
9476
9477    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9478            boolean removeFromRecents) {
9479        if (removeFromRecents) {
9480            mRecentTasks.remove(tr);
9481            tr.removedFromRecents();
9482        }
9483        ComponentName component = tr.getBaseIntent().getComponent();
9484        if (component == null) {
9485            Slog.w(TAG, "No component for base intent of task: " + tr);
9486            return;
9487        }
9488
9489        // Find any running services associated with this app and stop if needed.
9490        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9491
9492        if (!killProcess) {
9493            return;
9494        }
9495
9496        // Determine if the process(es) for this task should be killed.
9497        final String pkg = component.getPackageName();
9498        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9499        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9500        for (int i = 0; i < pmap.size(); i++) {
9501
9502            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9503            for (int j = 0; j < uids.size(); j++) {
9504                ProcessRecord proc = uids.valueAt(j);
9505                if (proc.userId != tr.userId) {
9506                    // Don't kill process for a different user.
9507                    continue;
9508                }
9509                if (proc == mHomeProcess) {
9510                    // Don't kill the home process along with tasks from the same package.
9511                    continue;
9512                }
9513                if (!proc.pkgList.containsKey(pkg)) {
9514                    // Don't kill process that is not associated with this task.
9515                    continue;
9516                }
9517
9518                for (int k = 0; k < proc.activities.size(); k++) {
9519                    TaskRecord otherTask = proc.activities.get(k).task;
9520                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9521                        // Don't kill process(es) that has an activity in a different task that is
9522                        // also in recents.
9523                        return;
9524                    }
9525                }
9526
9527                if (proc.foregroundServices) {
9528                    // Don't kill process(es) with foreground service.
9529                    return;
9530                }
9531
9532                // Add process to kill list.
9533                procsToKill.add(proc);
9534            }
9535        }
9536
9537        // Kill the running processes.
9538        for (int i = 0; i < procsToKill.size(); i++) {
9539            ProcessRecord pr = procsToKill.get(i);
9540            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9541                    && pr.curReceiver == null) {
9542                pr.kill("remove task", true);
9543            } else {
9544                // We delay killing processes that are not in the background or running a receiver.
9545                pr.waitingToKill = "remove task";
9546            }
9547        }
9548    }
9549
9550    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9551        // Remove all tasks with activities in the specified package from the list of recent tasks
9552        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9553            TaskRecord tr = mRecentTasks.get(i);
9554            if (tr.userId != userId) continue;
9555
9556            ComponentName cn = tr.intent.getComponent();
9557            if (cn != null && cn.getPackageName().equals(packageName)) {
9558                // If the package name matches, remove the task.
9559                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9560            }
9561        }
9562    }
9563
9564    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9565            int userId) {
9566
9567        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9568            TaskRecord tr = mRecentTasks.get(i);
9569            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9570                continue;
9571            }
9572
9573            ComponentName cn = tr.intent.getComponent();
9574            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9575                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9576            if (sameComponent) {
9577                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9578            }
9579        }
9580    }
9581
9582    /**
9583     * Removes the task with the specified task id.
9584     *
9585     * @param taskId Identifier of the task to be removed.
9586     * @param killProcess Kill any process associated with the task if possible.
9587     * @param removeFromRecents Whether to also remove the task from recents.
9588     * @return Returns true if the given task was found and removed.
9589     */
9590    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9591            boolean removeFromRecents) {
9592        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9593                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9594        if (tr != null) {
9595            tr.removeTaskActivitiesLocked();
9596            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9597            if (tr.isPersistable) {
9598                notifyTaskPersisterLocked(null, true);
9599            }
9600            return true;
9601        }
9602        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9603        return false;
9604    }
9605
9606    @Override
9607    public void removeStack(int stackId) {
9608        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9609        if (stackId == HOME_STACK_ID) {
9610            throw new IllegalArgumentException("Removing home stack is not allowed.");
9611        }
9612
9613        synchronized (this) {
9614            final long ident = Binder.clearCallingIdentity();
9615            try {
9616                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9617                if (stack == null) {
9618                    return;
9619                }
9620                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9621                for (int i = tasks.size() - 1; i >= 0; i--) {
9622                    removeTaskByIdLocked(
9623                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9624                }
9625            } finally {
9626                Binder.restoreCallingIdentity(ident);
9627            }
9628        }
9629    }
9630
9631    @Override
9632    public boolean removeTask(int taskId) {
9633        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9634        synchronized (this) {
9635            final long ident = Binder.clearCallingIdentity();
9636            try {
9637                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9638            } finally {
9639                Binder.restoreCallingIdentity(ident);
9640            }
9641        }
9642    }
9643
9644    /**
9645     * TODO: Add mController hook
9646     */
9647    @Override
9648    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9649        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9650
9651        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9652        synchronized(this) {
9653            moveTaskToFrontLocked(taskId, flags, bOptions);
9654        }
9655    }
9656
9657    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9658        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9659
9660        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9661                Binder.getCallingUid(), -1, -1, "Task to front")) {
9662            ActivityOptions.abort(options);
9663            return;
9664        }
9665        final long origId = Binder.clearCallingIdentity();
9666        try {
9667            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9668            if (task == null) {
9669                Slog.d(TAG, "Could not find task for id: "+ taskId);
9670                return;
9671            }
9672            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9673                mStackSupervisor.showLockTaskToast();
9674                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9675                return;
9676            }
9677            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9678            if (prev != null && prev.isRecentsActivity()) {
9679                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9680            }
9681            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9682                    false /* forceNonResizable */);
9683        } finally {
9684            Binder.restoreCallingIdentity(origId);
9685        }
9686        ActivityOptions.abort(options);
9687    }
9688
9689    /**
9690     * Moves an activity, and all of the other activities within the same task, to the bottom
9691     * of the history stack.  The activity's order within the task is unchanged.
9692     *
9693     * @param token A reference to the activity we wish to move
9694     * @param nonRoot If false then this only works if the activity is the root
9695     *                of a task; if true it will work for any activity in a task.
9696     * @return Returns true if the move completed, false if not.
9697     */
9698    @Override
9699    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9700        enforceNotIsolatedCaller("moveActivityTaskToBack");
9701        synchronized(this) {
9702            final long origId = Binder.clearCallingIdentity();
9703            try {
9704                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9705                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9706                if (task != null) {
9707                    if (mStackSupervisor.isLockedTask(task)) {
9708                        mStackSupervisor.showLockTaskToast();
9709                        return false;
9710                    }
9711                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9712                }
9713            } finally {
9714                Binder.restoreCallingIdentity(origId);
9715            }
9716        }
9717        return false;
9718    }
9719
9720    @Override
9721    public void moveTaskBackwards(int task) {
9722        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9723                "moveTaskBackwards()");
9724
9725        synchronized(this) {
9726            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9727                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9728                return;
9729            }
9730            final long origId = Binder.clearCallingIdentity();
9731            moveTaskBackwardsLocked(task);
9732            Binder.restoreCallingIdentity(origId);
9733        }
9734    }
9735
9736    private final void moveTaskBackwardsLocked(int task) {
9737        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9738    }
9739
9740    @Override
9741    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9742            IActivityContainerCallback callback) throws RemoteException {
9743        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9744        synchronized (this) {
9745            if (parentActivityToken == null) {
9746                throw new IllegalArgumentException("parent token must not be null");
9747            }
9748            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9749            if (r == null) {
9750                return null;
9751            }
9752            if (callback == null) {
9753                throw new IllegalArgumentException("callback must not be null");
9754            }
9755            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9756        }
9757    }
9758
9759    @Override
9760    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9761        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9762        synchronized (this) {
9763            mStackSupervisor.deleteActivityContainer(container);
9764        }
9765    }
9766
9767    @Override
9768    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9769        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9770        synchronized (this) {
9771            final int stackId = mStackSupervisor.getNextStackId();
9772            final ActivityStack stack =
9773                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9774            if (stack == null) {
9775                return null;
9776            }
9777            return stack.mActivityContainer;
9778        }
9779    }
9780
9781    @Override
9782    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9783        synchronized (this) {
9784            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9785            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9786                return stack.mActivityContainer.getDisplayId();
9787            }
9788            return Display.DEFAULT_DISPLAY;
9789        }
9790    }
9791
9792    @Override
9793    public int getActivityStackId(IBinder token) throws RemoteException {
9794        synchronized (this) {
9795            ActivityStack stack = ActivityRecord.getStackLocked(token);
9796            if (stack == null) {
9797                return INVALID_STACK_ID;
9798            }
9799            return stack.mStackId;
9800        }
9801    }
9802
9803    @Override
9804    public void exitFreeformMode(IBinder token) throws RemoteException {
9805        synchronized (this) {
9806            long ident = Binder.clearCallingIdentity();
9807            try {
9808                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9809                if (r == null) {
9810                    throw new IllegalArgumentException(
9811                            "exitFreeformMode: No activity record matching token=" + token);
9812                }
9813                final ActivityStack stack = r.getStackLocked(token);
9814                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9815                    throw new IllegalStateException(
9816                            "exitFreeformMode: You can only go fullscreen from freeform.");
9817                }
9818                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9819                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9820                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9821            } finally {
9822                Binder.restoreCallingIdentity(ident);
9823            }
9824        }
9825    }
9826
9827    @Override
9828    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9829        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9830        if (stackId == HOME_STACK_ID) {
9831            throw new IllegalArgumentException(
9832                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9833        }
9834        synchronized (this) {
9835            long ident = Binder.clearCallingIdentity();
9836            try {
9837                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9838                        + " to stackId=" + stackId + " toTop=" + toTop);
9839                if (stackId == DOCKED_STACK_ID) {
9840                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9841                            null /* initialBounds */);
9842                }
9843                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9844                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9845                if (result && stackId == DOCKED_STACK_ID) {
9846                    // If task moved to docked stack - show recents if needed.
9847                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9848                            "moveTaskToDockedStack");
9849                }
9850            } finally {
9851                Binder.restoreCallingIdentity(ident);
9852            }
9853        }
9854    }
9855
9856    @Override
9857    public void swapDockedAndFullscreenStack() throws RemoteException {
9858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9859        synchronized (this) {
9860            long ident = Binder.clearCallingIdentity();
9861            try {
9862                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9863                        FULLSCREEN_WORKSPACE_STACK_ID);
9864                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9865                        : null;
9866                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9867                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9868                        : null;
9869                if (topTask == null || tasks == null || tasks.size() == 0) {
9870                    Slog.w(TAG,
9871                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9872                    return;
9873                }
9874
9875                // TODO: App transition
9876                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9877
9878                // Defer the resume so resume/pausing while moving stacks is dangerous.
9879                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9880                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9881                        ANIMATE, true /* deferResume */);
9882                final int size = tasks.size();
9883                for (int i = 0; i < size; i++) {
9884                    final int id = tasks.get(i).taskId;
9885                    if (id == topTask.taskId) {
9886                        continue;
9887                    }
9888                    mStackSupervisor.moveTaskToStackLocked(id,
9889                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9890                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9891                }
9892
9893                // Because we deferred the resume, to avoid conflicts with stack switches while
9894                // resuming, we need to do it after all the tasks are moved.
9895                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9896                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9897
9898                mWindowManager.executeAppTransition();
9899            } finally {
9900                Binder.restoreCallingIdentity(ident);
9901            }
9902        }
9903    }
9904
9905    /**
9906     * Moves the input task to the docked stack.
9907     *
9908     * @param taskId Id of task to move.
9909     * @param createMode The mode the docked stack should be created in if it doesn't exist
9910     *                   already. See
9911     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9912     *                   and
9913     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9914     * @param toTop If the task and stack should be moved to the top.
9915     * @param animate Whether we should play an animation for the moving the task
9916     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9917     *                      docked stack. Pass {@code null} to use default bounds.
9918     */
9919    @Override
9920    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9921            Rect initialBounds, boolean moveHomeStackFront) {
9922        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9923        synchronized (this) {
9924            long ident = Binder.clearCallingIdentity();
9925            try {
9926                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9927                        + " to createMode=" + createMode + " toTop=" + toTop);
9928                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9929                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9930                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9931                        animate, DEFER_RESUME);
9932                if (moved) {
9933                    if (moveHomeStackFront) {
9934                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9935                    }
9936                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9937                }
9938                return moved;
9939            } finally {
9940                Binder.restoreCallingIdentity(ident);
9941            }
9942        }
9943    }
9944
9945    /**
9946     * Moves the top activity in the input stackId to the pinned stack.
9947     *
9948     * @param stackId Id of stack to move the top activity to pinned stack.
9949     * @param bounds Bounds to use for pinned stack.
9950     *
9951     * @return True if the top activity of the input stack was successfully moved to the pinned
9952     *          stack.
9953     */
9954    @Override
9955    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9956        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9957        synchronized (this) {
9958            if (!mSupportsPictureInPicture) {
9959                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9960                        + "Device doesn't support picture-in-pciture mode");
9961            }
9962
9963            long ident = Binder.clearCallingIdentity();
9964            try {
9965                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9966            } finally {
9967                Binder.restoreCallingIdentity(ident);
9968            }
9969        }
9970    }
9971
9972    @Override
9973    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9974            boolean preserveWindows, boolean animate, int animationDuration) {
9975        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9976        long ident = Binder.clearCallingIdentity();
9977        try {
9978            synchronized (this) {
9979                if (animate) {
9980                    if (stackId == PINNED_STACK_ID) {
9981                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9982                    } else {
9983                        throw new IllegalArgumentException("Stack: " + stackId
9984                                + " doesn't support animated resize.");
9985                    }
9986                } else {
9987                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9988                            null /* tempTaskInsetBounds */, preserveWindows,
9989                            allowResizeInDockedMode, !DEFER_RESUME);
9990                }
9991            }
9992        } finally {
9993            Binder.restoreCallingIdentity(ident);
9994        }
9995    }
9996
9997    @Override
9998    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9999            Rect tempDockedTaskInsetBounds,
10000            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10001        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10002                "resizeDockedStack()");
10003        long ident = Binder.clearCallingIdentity();
10004        try {
10005            synchronized (this) {
10006                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10007                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10008                        PRESERVE_WINDOWS);
10009            }
10010        } finally {
10011            Binder.restoreCallingIdentity(ident);
10012        }
10013    }
10014
10015    @Override
10016    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10017        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10018                "resizePinnedStack()");
10019        final long ident = Binder.clearCallingIdentity();
10020        try {
10021            synchronized (this) {
10022                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10023            }
10024        } finally {
10025            Binder.restoreCallingIdentity(ident);
10026        }
10027    }
10028
10029    @Override
10030    public void positionTaskInStack(int taskId, int stackId, int position) {
10031        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10032        if (stackId == HOME_STACK_ID) {
10033            throw new IllegalArgumentException(
10034                    "positionTaskInStack: Attempt to change the position of task "
10035                    + taskId + " in/to home stack");
10036        }
10037        synchronized (this) {
10038            long ident = Binder.clearCallingIdentity();
10039            try {
10040                if (DEBUG_STACK) Slog.d(TAG_STACK,
10041                        "positionTaskInStack: positioning task=" + taskId
10042                        + " in stackId=" + stackId + " at position=" + position);
10043                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10044            } finally {
10045                Binder.restoreCallingIdentity(ident);
10046            }
10047        }
10048    }
10049
10050    @Override
10051    public List<StackInfo> getAllStackInfos() {
10052        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10053        long ident = Binder.clearCallingIdentity();
10054        try {
10055            synchronized (this) {
10056                return mStackSupervisor.getAllStackInfosLocked();
10057            }
10058        } finally {
10059            Binder.restoreCallingIdentity(ident);
10060        }
10061    }
10062
10063    @Override
10064    public StackInfo getStackInfo(int stackId) {
10065        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10066        long ident = Binder.clearCallingIdentity();
10067        try {
10068            synchronized (this) {
10069                return mStackSupervisor.getStackInfoLocked(stackId);
10070            }
10071        } finally {
10072            Binder.restoreCallingIdentity(ident);
10073        }
10074    }
10075
10076    @Override
10077    public boolean isInHomeStack(int taskId) {
10078        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10079        long ident = Binder.clearCallingIdentity();
10080        try {
10081            synchronized (this) {
10082                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10083                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10084                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10085            }
10086        } finally {
10087            Binder.restoreCallingIdentity(ident);
10088        }
10089    }
10090
10091    @Override
10092    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10093        synchronized(this) {
10094            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10095        }
10096    }
10097
10098    @Override
10099    public void updateDeviceOwner(String packageName) {
10100        final int callingUid = Binder.getCallingUid();
10101        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10102            throw new SecurityException("updateDeviceOwner called from non-system process");
10103        }
10104        synchronized (this) {
10105            mDeviceOwnerName = packageName;
10106        }
10107    }
10108
10109    @Override
10110    public void updateLockTaskPackages(int userId, String[] packages) {
10111        final int callingUid = Binder.getCallingUid();
10112        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10113            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10114                    "updateLockTaskPackages()");
10115        }
10116        synchronized (this) {
10117            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10118                    Arrays.toString(packages));
10119            mLockTaskPackages.put(userId, packages);
10120            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10121        }
10122    }
10123
10124
10125    void startLockTaskModeLocked(TaskRecord task) {
10126        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10127        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10128            return;
10129        }
10130
10131        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10132        // is initiated by system after the pinning request was shown and locked mode is initiated
10133        // by an authorized app directly
10134        final int callingUid = Binder.getCallingUid();
10135        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10136        long ident = Binder.clearCallingIdentity();
10137        try {
10138            if (!isSystemInitiated) {
10139                task.mLockTaskUid = callingUid;
10140                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10141                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10142                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10143                    StatusBarManagerInternal statusBarManager =
10144                            LocalServices.getService(StatusBarManagerInternal.class);
10145                    if (statusBarManager != null) {
10146                        statusBarManager.showScreenPinningRequest(task.taskId);
10147                    }
10148                    return;
10149                }
10150
10151                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10152                if (stack == null || task != stack.topTask()) {
10153                    throw new IllegalArgumentException("Invalid task, not in foreground");
10154                }
10155            }
10156            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10157                    "Locking fully");
10158            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10159                    ActivityManager.LOCK_TASK_MODE_PINNED :
10160                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10161                    "startLockTask", true);
10162        } finally {
10163            Binder.restoreCallingIdentity(ident);
10164        }
10165    }
10166
10167    @Override
10168    public void startLockTaskMode(int taskId) {
10169        synchronized (this) {
10170            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10171            if (task != null) {
10172                startLockTaskModeLocked(task);
10173            }
10174        }
10175    }
10176
10177    @Override
10178    public void startLockTaskMode(IBinder token) {
10179        synchronized (this) {
10180            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10181            if (r == null) {
10182                return;
10183            }
10184            final TaskRecord task = r.task;
10185            if (task != null) {
10186                startLockTaskModeLocked(task);
10187            }
10188        }
10189    }
10190
10191    @Override
10192    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10193        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10194        // This makes inner call to look as if it was initiated by system.
10195        long ident = Binder.clearCallingIdentity();
10196        try {
10197            synchronized (this) {
10198                startLockTaskMode(taskId);
10199            }
10200        } finally {
10201            Binder.restoreCallingIdentity(ident);
10202        }
10203    }
10204
10205    @Override
10206    public void stopLockTaskMode() {
10207        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10208        if (lockTask == null) {
10209            // Our work here is done.
10210            return;
10211        }
10212
10213        final int callingUid = Binder.getCallingUid();
10214        final int lockTaskUid = lockTask.mLockTaskUid;
10215        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10216        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10217            // Done.
10218            return;
10219        } else {
10220            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10221            // It is possible lockTaskMode was started by the system process because
10222            // android:lockTaskMode is set to a locking value in the application manifest
10223            // instead of the app calling startLockTaskMode. In this case
10224            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10225            // {@link TaskRecord.effectiveUid} instead. Also caller with
10226            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10227            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10228                    && callingUid != lockTaskUid
10229                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10230                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10231                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10232            }
10233        }
10234        long ident = Binder.clearCallingIdentity();
10235        try {
10236            Log.d(TAG, "stopLockTaskMode");
10237            // Stop lock task
10238            synchronized (this) {
10239                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10240                        "stopLockTask", true);
10241            }
10242            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10243            if (tm != null) {
10244                tm.showInCallScreen(false);
10245            }
10246        } finally {
10247            Binder.restoreCallingIdentity(ident);
10248        }
10249    }
10250
10251    /**
10252     * This API should be called by SystemUI only when user perform certain action to dismiss
10253     * lock task mode. We should only dismiss pinned lock task mode in this case.
10254     */
10255    @Override
10256    public void stopSystemLockTaskMode() throws RemoteException {
10257        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10258            stopLockTaskMode();
10259        } else {
10260            mStackSupervisor.showLockTaskToast();
10261        }
10262    }
10263
10264    @Override
10265    public boolean isInLockTaskMode() {
10266        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10267    }
10268
10269    @Override
10270    public int getLockTaskModeState() {
10271        synchronized (this) {
10272            return mStackSupervisor.getLockTaskModeState();
10273        }
10274    }
10275
10276    @Override
10277    public void showLockTaskEscapeMessage(IBinder token) {
10278        synchronized (this) {
10279            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10280            if (r == null) {
10281                return;
10282            }
10283            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10284        }
10285    }
10286
10287    // =========================================================
10288    // CONTENT PROVIDERS
10289    // =========================================================
10290
10291    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10292        List<ProviderInfo> providers = null;
10293        try {
10294            providers = AppGlobals.getPackageManager()
10295                    .queryContentProviders(app.processName, app.uid,
10296                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10297                                    | MATCH_DEBUG_TRIAGED_MISSING)
10298                    .getList();
10299        } catch (RemoteException ex) {
10300        }
10301        if (DEBUG_MU) Slog.v(TAG_MU,
10302                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10303        int userId = app.userId;
10304        if (providers != null) {
10305            int N = providers.size();
10306            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10307            for (int i=0; i<N; i++) {
10308                // TODO: keep logic in sync with installEncryptionUnawareProviders
10309                ProviderInfo cpi =
10310                    (ProviderInfo)providers.get(i);
10311                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10312                        cpi.name, cpi.flags);
10313                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10314                    // This is a singleton provider, but a user besides the
10315                    // default user is asking to initialize a process it runs
10316                    // in...  well, no, it doesn't actually run in this process,
10317                    // it runs in the process of the default user.  Get rid of it.
10318                    providers.remove(i);
10319                    N--;
10320                    i--;
10321                    continue;
10322                }
10323
10324                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10325                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10326                if (cpr == null) {
10327                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10328                    mProviderMap.putProviderByClass(comp, cpr);
10329                }
10330                if (DEBUG_MU) Slog.v(TAG_MU,
10331                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10332                app.pubProviders.put(cpi.name, cpr);
10333                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10334                    // Don't add this if it is a platform component that is marked
10335                    // to run in multiple processes, because this is actually
10336                    // part of the framework so doesn't make sense to track as a
10337                    // separate apk in the process.
10338                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10339                            mProcessStats);
10340                }
10341                notifyPackageUse(cpi.applicationInfo.packageName,
10342                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10343            }
10344        }
10345        return providers;
10346    }
10347
10348    /**
10349     * Check if {@link ProcessRecord} has a possible chance at accessing the
10350     * given {@link ProviderInfo}. Final permission checking is always done
10351     * in {@link ContentProvider}.
10352     */
10353    private final String checkContentProviderPermissionLocked(
10354            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10355        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10356        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10357        boolean checkedGrants = false;
10358        if (checkUser) {
10359            // Looking for cross-user grants before enforcing the typical cross-users permissions
10360            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10361            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10362                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10363                    return null;
10364                }
10365                checkedGrants = true;
10366            }
10367            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10368                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10369            if (userId != tmpTargetUserId) {
10370                // When we actually went to determine the final targer user ID, this ended
10371                // up different than our initial check for the authority.  This is because
10372                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10373                // SELF.  So we need to re-check the grants again.
10374                checkedGrants = false;
10375            }
10376        }
10377        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10378                cpi.applicationInfo.uid, cpi.exported)
10379                == PackageManager.PERMISSION_GRANTED) {
10380            return null;
10381        }
10382        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10383                cpi.applicationInfo.uid, cpi.exported)
10384                == PackageManager.PERMISSION_GRANTED) {
10385            return null;
10386        }
10387
10388        PathPermission[] pps = cpi.pathPermissions;
10389        if (pps != null) {
10390            int i = pps.length;
10391            while (i > 0) {
10392                i--;
10393                PathPermission pp = pps[i];
10394                String pprperm = pp.getReadPermission();
10395                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10396                        cpi.applicationInfo.uid, cpi.exported)
10397                        == PackageManager.PERMISSION_GRANTED) {
10398                    return null;
10399                }
10400                String ppwperm = pp.getWritePermission();
10401                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10402                        cpi.applicationInfo.uid, cpi.exported)
10403                        == PackageManager.PERMISSION_GRANTED) {
10404                    return null;
10405                }
10406            }
10407        }
10408        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10409            return null;
10410        }
10411
10412        String msg;
10413        if (!cpi.exported) {
10414            msg = "Permission Denial: opening provider " + cpi.name
10415                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10416                    + ", uid=" + callingUid + ") that is not exported from uid "
10417                    + cpi.applicationInfo.uid;
10418        } else {
10419            msg = "Permission Denial: opening provider " + cpi.name
10420                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10421                    + ", uid=" + callingUid + ") requires "
10422                    + cpi.readPermission + " or " + cpi.writePermission;
10423        }
10424        Slog.w(TAG, msg);
10425        return msg;
10426    }
10427
10428    /**
10429     * Returns if the ContentProvider has granted a uri to callingUid
10430     */
10431    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10432        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10433        if (perms != null) {
10434            for (int i=perms.size()-1; i>=0; i--) {
10435                GrantUri grantUri = perms.keyAt(i);
10436                if (grantUri.sourceUserId == userId || !checkUser) {
10437                    if (matchesProvider(grantUri.uri, cpi)) {
10438                        return true;
10439                    }
10440                }
10441            }
10442        }
10443        return false;
10444    }
10445
10446    /**
10447     * Returns true if the uri authority is one of the authorities specified in the provider.
10448     */
10449    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10450        String uriAuth = uri.getAuthority();
10451        String cpiAuth = cpi.authority;
10452        if (cpiAuth.indexOf(';') == -1) {
10453            return cpiAuth.equals(uriAuth);
10454        }
10455        String[] cpiAuths = cpiAuth.split(";");
10456        int length = cpiAuths.length;
10457        for (int i = 0; i < length; i++) {
10458            if (cpiAuths[i].equals(uriAuth)) return true;
10459        }
10460        return false;
10461    }
10462
10463    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10464            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10465        if (r != null) {
10466            for (int i=0; i<r.conProviders.size(); i++) {
10467                ContentProviderConnection conn = r.conProviders.get(i);
10468                if (conn.provider == cpr) {
10469                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10470                            "Adding provider requested by "
10471                            + r.processName + " from process "
10472                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10473                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10474                    if (stable) {
10475                        conn.stableCount++;
10476                        conn.numStableIncs++;
10477                    } else {
10478                        conn.unstableCount++;
10479                        conn.numUnstableIncs++;
10480                    }
10481                    return conn;
10482                }
10483            }
10484            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10485            if (stable) {
10486                conn.stableCount = 1;
10487                conn.numStableIncs = 1;
10488            } else {
10489                conn.unstableCount = 1;
10490                conn.numUnstableIncs = 1;
10491            }
10492            cpr.connections.add(conn);
10493            r.conProviders.add(conn);
10494            startAssociationLocked(r.uid, r.processName, r.curProcState,
10495                    cpr.uid, cpr.name, cpr.info.processName);
10496            return conn;
10497        }
10498        cpr.addExternalProcessHandleLocked(externalProcessToken);
10499        return null;
10500    }
10501
10502    boolean decProviderCountLocked(ContentProviderConnection conn,
10503            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10504        if (conn != null) {
10505            cpr = conn.provider;
10506            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10507                    "Removing provider requested by "
10508                    + conn.client.processName + " from process "
10509                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10510                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10511            if (stable) {
10512                conn.stableCount--;
10513            } else {
10514                conn.unstableCount--;
10515            }
10516            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10517                cpr.connections.remove(conn);
10518                conn.client.conProviders.remove(conn);
10519                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10520                    // The client is more important than last activity -- note the time this
10521                    // is happening, so we keep the old provider process around a bit as last
10522                    // activity to avoid thrashing it.
10523                    if (cpr.proc != null) {
10524                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10525                    }
10526                }
10527                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10528                return true;
10529            }
10530            return false;
10531        }
10532        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10533        return false;
10534    }
10535
10536    private void checkTime(long startTime, String where) {
10537        long now = SystemClock.uptimeMillis();
10538        if ((now-startTime) > 50) {
10539            // If we are taking more than 50ms, log about it.
10540            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10541        }
10542    }
10543
10544    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10545            PROC_SPACE_TERM,
10546            PROC_SPACE_TERM|PROC_PARENS,
10547            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10548    };
10549
10550    private final long[] mProcessStateStatsLongs = new long[1];
10551
10552    boolean isProcessAliveLocked(ProcessRecord proc) {
10553        if (proc.procStatFile == null) {
10554            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10555        }
10556        mProcessStateStatsLongs[0] = 0;
10557        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10558                mProcessStateStatsLongs, null)) {
10559            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10560            return false;
10561        }
10562        final long state = mProcessStateStatsLongs[0];
10563        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10564                + (char)state);
10565        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10566    }
10567
10568    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10569            String name, IBinder token, boolean stable, int userId) {
10570        ContentProviderRecord cpr;
10571        ContentProviderConnection conn = null;
10572        ProviderInfo cpi = null;
10573
10574        synchronized(this) {
10575            long startTime = SystemClock.uptimeMillis();
10576
10577            ProcessRecord r = null;
10578            if (caller != null) {
10579                r = getRecordForAppLocked(caller);
10580                if (r == null) {
10581                    throw new SecurityException(
10582                            "Unable to find app for caller " + caller
10583                          + " (pid=" + Binder.getCallingPid()
10584                          + ") when getting content provider " + name);
10585                }
10586            }
10587
10588            boolean checkCrossUser = true;
10589
10590            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10591
10592            // First check if this content provider has been published...
10593            cpr = mProviderMap.getProviderByName(name, userId);
10594            // If that didn't work, check if it exists for user 0 and then
10595            // verify that it's a singleton provider before using it.
10596            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10597                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10598                if (cpr != null) {
10599                    cpi = cpr.info;
10600                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10601                            cpi.name, cpi.flags)
10602                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10603                        userId = UserHandle.USER_SYSTEM;
10604                        checkCrossUser = false;
10605                    } else {
10606                        cpr = null;
10607                        cpi = null;
10608                    }
10609                }
10610            }
10611
10612            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10613            if (providerRunning) {
10614                cpi = cpr.info;
10615                String msg;
10616                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10617                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10618                        != null) {
10619                    throw new SecurityException(msg);
10620                }
10621                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10622
10623                if (r != null && cpr.canRunHere(r)) {
10624                    // This provider has been published or is in the process
10625                    // of being published...  but it is also allowed to run
10626                    // in the caller's process, so don't make a connection
10627                    // and just let the caller instantiate its own instance.
10628                    ContentProviderHolder holder = cpr.newHolder(null);
10629                    // don't give caller the provider object, it needs
10630                    // to make its own.
10631                    holder.provider = null;
10632                    return holder;
10633                }
10634
10635                final long origId = Binder.clearCallingIdentity();
10636
10637                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10638
10639                // In this case the provider instance already exists, so we can
10640                // return it right away.
10641                conn = incProviderCountLocked(r, cpr, token, stable);
10642                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10643                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10644                        // If this is a perceptible app accessing the provider,
10645                        // make sure to count it as being accessed and thus
10646                        // back up on the LRU list.  This is good because
10647                        // content providers are often expensive to start.
10648                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10649                        updateLruProcessLocked(cpr.proc, false, null);
10650                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10651                    }
10652                }
10653
10654                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10655                final int verifiedAdj = cpr.proc.verifiedAdj;
10656                boolean success = updateOomAdjLocked(cpr.proc);
10657                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10658                // if the process has been successfully adjusted.  So to reduce races with
10659                // it, we will check whether the process still exists.  Note that this doesn't
10660                // completely get rid of races with LMK killing the process, but should make
10661                // them much smaller.
10662                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10663                    success = false;
10664                }
10665                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10666                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10667                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10668                // NOTE: there is still a race here where a signal could be
10669                // pending on the process even though we managed to update its
10670                // adj level.  Not sure what to do about this, but at least
10671                // the race is now smaller.
10672                if (!success) {
10673                    // Uh oh...  it looks like the provider's process
10674                    // has been killed on us.  We need to wait for a new
10675                    // process to be started, and make sure its death
10676                    // doesn't kill our process.
10677                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10678                            + " is crashing; detaching " + r);
10679                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10680                    checkTime(startTime, "getContentProviderImpl: before appDied");
10681                    appDiedLocked(cpr.proc);
10682                    checkTime(startTime, "getContentProviderImpl: after appDied");
10683                    if (!lastRef) {
10684                        // This wasn't the last ref our process had on
10685                        // the provider...  we have now been killed, bail.
10686                        return null;
10687                    }
10688                    providerRunning = false;
10689                    conn = null;
10690                } else {
10691                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10692                }
10693
10694                Binder.restoreCallingIdentity(origId);
10695            }
10696
10697            if (!providerRunning) {
10698                try {
10699                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10700                    cpi = AppGlobals.getPackageManager().
10701                        resolveContentProvider(name,
10702                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10703                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10704                } catch (RemoteException ex) {
10705                }
10706                if (cpi == null) {
10707                    return null;
10708                }
10709                // If the provider is a singleton AND
10710                // (it's a call within the same user || the provider is a
10711                // privileged app)
10712                // Then allow connecting to the singleton provider
10713                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10714                        cpi.name, cpi.flags)
10715                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10716                if (singleton) {
10717                    userId = UserHandle.USER_SYSTEM;
10718                }
10719                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10720                checkTime(startTime, "getContentProviderImpl: got app info for user");
10721
10722                String msg;
10723                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10724                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10725                        != null) {
10726                    throw new SecurityException(msg);
10727                }
10728                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10729
10730                if (!mProcessesReady
10731                        && !cpi.processName.equals("system")) {
10732                    // If this content provider does not run in the system
10733                    // process, and the system is not yet ready to run other
10734                    // processes, then fail fast instead of hanging.
10735                    throw new IllegalArgumentException(
10736                            "Attempt to launch content provider before system ready");
10737                }
10738
10739                // Make sure that the user who owns this provider is running.  If not,
10740                // we don't want to allow it to run.
10741                if (!mUserController.isUserRunningLocked(userId, 0)) {
10742                    Slog.w(TAG, "Unable to launch app "
10743                            + cpi.applicationInfo.packageName + "/"
10744                            + cpi.applicationInfo.uid + " for provider "
10745                            + name + ": user " + userId + " is stopped");
10746                    return null;
10747                }
10748
10749                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10750                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10751                cpr = mProviderMap.getProviderByClass(comp, userId);
10752                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10753                final boolean firstClass = cpr == null;
10754                if (firstClass) {
10755                    final long ident = Binder.clearCallingIdentity();
10756
10757                    // If permissions need a review before any of the app components can run,
10758                    // we return no provider and launch a review activity if the calling app
10759                    // is in the foreground.
10760                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10761                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10762                            return null;
10763                        }
10764                    }
10765
10766                    try {
10767                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10768                        ApplicationInfo ai =
10769                            AppGlobals.getPackageManager().
10770                                getApplicationInfo(
10771                                        cpi.applicationInfo.packageName,
10772                                        STOCK_PM_FLAGS, userId);
10773                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10774                        if (ai == null) {
10775                            Slog.w(TAG, "No package info for content provider "
10776                                    + cpi.name);
10777                            return null;
10778                        }
10779                        ai = getAppInfoForUser(ai, userId);
10780                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10781                    } catch (RemoteException ex) {
10782                        // pm is in same process, this will never happen.
10783                    } finally {
10784                        Binder.restoreCallingIdentity(ident);
10785                    }
10786                }
10787
10788                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10789
10790                if (r != null && cpr.canRunHere(r)) {
10791                    // If this is a multiprocess provider, then just return its
10792                    // info and allow the caller to instantiate it.  Only do
10793                    // this if the provider is the same user as the caller's
10794                    // process, or can run as root (so can be in any process).
10795                    return cpr.newHolder(null);
10796                }
10797
10798                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10799                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10800                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10801
10802                // This is single process, and our app is now connecting to it.
10803                // See if we are already in the process of launching this
10804                // provider.
10805                final int N = mLaunchingProviders.size();
10806                int i;
10807                for (i = 0; i < N; i++) {
10808                    if (mLaunchingProviders.get(i) == cpr) {
10809                        break;
10810                    }
10811                }
10812
10813                // If the provider is not already being launched, then get it
10814                // started.
10815                if (i >= N) {
10816                    final long origId = Binder.clearCallingIdentity();
10817
10818                    try {
10819                        // Content provider is now in use, its package can't be stopped.
10820                        try {
10821                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10822                            AppGlobals.getPackageManager().setPackageStoppedState(
10823                                    cpr.appInfo.packageName, false, userId);
10824                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10825                        } catch (RemoteException e) {
10826                        } catch (IllegalArgumentException e) {
10827                            Slog.w(TAG, "Failed trying to unstop package "
10828                                    + cpr.appInfo.packageName + ": " + e);
10829                        }
10830
10831                        // Use existing process if already started
10832                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10833                        ProcessRecord proc = getProcessRecordLocked(
10834                                cpi.processName, cpr.appInfo.uid, false);
10835                        if (proc != null && proc.thread != null && !proc.killed) {
10836                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10837                                    "Installing in existing process " + proc);
10838                            if (!proc.pubProviders.containsKey(cpi.name)) {
10839                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10840                                proc.pubProviders.put(cpi.name, cpr);
10841                                try {
10842                                    proc.thread.scheduleInstallProvider(cpi);
10843                                } catch (RemoteException e) {
10844                                }
10845                            }
10846                        } else {
10847                            checkTime(startTime, "getContentProviderImpl: before start process");
10848                            proc = startProcessLocked(cpi.processName,
10849                                    cpr.appInfo, false, 0, "content provider",
10850                                    new ComponentName(cpi.applicationInfo.packageName,
10851                                            cpi.name), false, false, false);
10852                            checkTime(startTime, "getContentProviderImpl: after start process");
10853                            if (proc == null) {
10854                                Slog.w(TAG, "Unable to launch app "
10855                                        + cpi.applicationInfo.packageName + "/"
10856                                        + cpi.applicationInfo.uid + " for provider "
10857                                        + name + ": process is bad");
10858                                return null;
10859                            }
10860                        }
10861                        cpr.launchingApp = proc;
10862                        mLaunchingProviders.add(cpr);
10863                    } finally {
10864                        Binder.restoreCallingIdentity(origId);
10865                    }
10866                }
10867
10868                checkTime(startTime, "getContentProviderImpl: updating data structures");
10869
10870                // Make sure the provider is published (the same provider class
10871                // may be published under multiple names).
10872                if (firstClass) {
10873                    mProviderMap.putProviderByClass(comp, cpr);
10874                }
10875
10876                mProviderMap.putProviderByName(name, cpr);
10877                conn = incProviderCountLocked(r, cpr, token, stable);
10878                if (conn != null) {
10879                    conn.waiting = true;
10880                }
10881            }
10882            checkTime(startTime, "getContentProviderImpl: done!");
10883        }
10884
10885        // Wait for the provider to be published...
10886        synchronized (cpr) {
10887            while (cpr.provider == null) {
10888                if (cpr.launchingApp == null) {
10889                    Slog.w(TAG, "Unable to launch app "
10890                            + cpi.applicationInfo.packageName + "/"
10891                            + cpi.applicationInfo.uid + " for provider "
10892                            + name + ": launching app became null");
10893                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10894                            UserHandle.getUserId(cpi.applicationInfo.uid),
10895                            cpi.applicationInfo.packageName,
10896                            cpi.applicationInfo.uid, name);
10897                    return null;
10898                }
10899                try {
10900                    if (DEBUG_MU) Slog.v(TAG_MU,
10901                            "Waiting to start provider " + cpr
10902                            + " launchingApp=" + cpr.launchingApp);
10903                    if (conn != null) {
10904                        conn.waiting = true;
10905                    }
10906                    cpr.wait();
10907                } catch (InterruptedException ex) {
10908                } finally {
10909                    if (conn != null) {
10910                        conn.waiting = false;
10911                    }
10912                }
10913            }
10914        }
10915        return cpr != null ? cpr.newHolder(conn) : null;
10916    }
10917
10918    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10919            ProcessRecord r, final int userId) {
10920        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10921                cpi.packageName, userId)) {
10922
10923            final boolean callerForeground = r == null || r.setSchedGroup
10924                    != ProcessList.SCHED_GROUP_BACKGROUND;
10925
10926            // Show a permission review UI only for starting from a foreground app
10927            if (!callerForeground) {
10928                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10929                        + cpi.packageName + " requires a permissions review");
10930                return false;
10931            }
10932
10933            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10934            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10935                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10936            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10937
10938            if (DEBUG_PERMISSIONS_REVIEW) {
10939                Slog.i(TAG, "u" + userId + " Launching permission review "
10940                        + "for package " + cpi.packageName);
10941            }
10942
10943            final UserHandle userHandle = new UserHandle(userId);
10944            mHandler.post(new Runnable() {
10945                @Override
10946                public void run() {
10947                    mContext.startActivityAsUser(intent, userHandle);
10948                }
10949            });
10950
10951            return false;
10952        }
10953
10954        return true;
10955    }
10956
10957    PackageManagerInternal getPackageManagerInternalLocked() {
10958        if (mPackageManagerInt == null) {
10959            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10960        }
10961        return mPackageManagerInt;
10962    }
10963
10964    @Override
10965    public final ContentProviderHolder getContentProvider(
10966            IApplicationThread caller, String name, int userId, boolean stable) {
10967        enforceNotIsolatedCaller("getContentProvider");
10968        if (caller == null) {
10969            String msg = "null IApplicationThread when getting content provider "
10970                    + name;
10971            Slog.w(TAG, msg);
10972            throw new SecurityException(msg);
10973        }
10974        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10975        // with cross-user grant.
10976        return getContentProviderImpl(caller, name, null, stable, userId);
10977    }
10978
10979    public ContentProviderHolder getContentProviderExternal(
10980            String name, int userId, IBinder token) {
10981        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10982            "Do not have permission in call getContentProviderExternal()");
10983        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10984                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10985        return getContentProviderExternalUnchecked(name, token, userId);
10986    }
10987
10988    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10989            IBinder token, int userId) {
10990        return getContentProviderImpl(null, name, token, true, userId);
10991    }
10992
10993    /**
10994     * Drop a content provider from a ProcessRecord's bookkeeping
10995     */
10996    public void removeContentProvider(IBinder connection, boolean stable) {
10997        enforceNotIsolatedCaller("removeContentProvider");
10998        long ident = Binder.clearCallingIdentity();
10999        try {
11000            synchronized (this) {
11001                ContentProviderConnection conn;
11002                try {
11003                    conn = (ContentProviderConnection)connection;
11004                } catch (ClassCastException e) {
11005                    String msg ="removeContentProvider: " + connection
11006                            + " not a ContentProviderConnection";
11007                    Slog.w(TAG, msg);
11008                    throw new IllegalArgumentException(msg);
11009                }
11010                if (conn == null) {
11011                    throw new NullPointerException("connection is null");
11012                }
11013                if (decProviderCountLocked(conn, null, null, stable)) {
11014                    updateOomAdjLocked();
11015                }
11016            }
11017        } finally {
11018            Binder.restoreCallingIdentity(ident);
11019        }
11020    }
11021
11022    public void removeContentProviderExternal(String name, IBinder token) {
11023        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11024            "Do not have permission in call removeContentProviderExternal()");
11025        int userId = UserHandle.getCallingUserId();
11026        long ident = Binder.clearCallingIdentity();
11027        try {
11028            removeContentProviderExternalUnchecked(name, token, userId);
11029        } finally {
11030            Binder.restoreCallingIdentity(ident);
11031        }
11032    }
11033
11034    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11035        synchronized (this) {
11036            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11037            if(cpr == null) {
11038                //remove from mProvidersByClass
11039                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11040                return;
11041            }
11042
11043            //update content provider record entry info
11044            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11045            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11046            if (localCpr.hasExternalProcessHandles()) {
11047                if (localCpr.removeExternalProcessHandleLocked(token)) {
11048                    updateOomAdjLocked();
11049                } else {
11050                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11051                            + " with no external reference for token: "
11052                            + token + ".");
11053                }
11054            } else {
11055                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11056                        + " with no external references.");
11057            }
11058        }
11059    }
11060
11061    public final void publishContentProviders(IApplicationThread caller,
11062            List<ContentProviderHolder> providers) {
11063        if (providers == null) {
11064            return;
11065        }
11066
11067        enforceNotIsolatedCaller("publishContentProviders");
11068        synchronized (this) {
11069            final ProcessRecord r = getRecordForAppLocked(caller);
11070            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11071            if (r == null) {
11072                throw new SecurityException(
11073                        "Unable to find app for caller " + caller
11074                      + " (pid=" + Binder.getCallingPid()
11075                      + ") when publishing content providers");
11076            }
11077
11078            final long origId = Binder.clearCallingIdentity();
11079
11080            final int N = providers.size();
11081            for (int i = 0; i < N; i++) {
11082                ContentProviderHolder src = providers.get(i);
11083                if (src == null || src.info == null || src.provider == null) {
11084                    continue;
11085                }
11086                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11087                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11088                if (dst != null) {
11089                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11090                    mProviderMap.putProviderByClass(comp, dst);
11091                    String names[] = dst.info.authority.split(";");
11092                    for (int j = 0; j < names.length; j++) {
11093                        mProviderMap.putProviderByName(names[j], dst);
11094                    }
11095
11096                    int launchingCount = mLaunchingProviders.size();
11097                    int j;
11098                    boolean wasInLaunchingProviders = false;
11099                    for (j = 0; j < launchingCount; j++) {
11100                        if (mLaunchingProviders.get(j) == dst) {
11101                            mLaunchingProviders.remove(j);
11102                            wasInLaunchingProviders = true;
11103                            j--;
11104                            launchingCount--;
11105                        }
11106                    }
11107                    if (wasInLaunchingProviders) {
11108                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11109                    }
11110                    synchronized (dst) {
11111                        dst.provider = src.provider;
11112                        dst.proc = r;
11113                        dst.notifyAll();
11114                    }
11115                    updateOomAdjLocked(r);
11116                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11117                            src.info.authority);
11118                }
11119            }
11120
11121            Binder.restoreCallingIdentity(origId);
11122        }
11123    }
11124
11125    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11126        ContentProviderConnection conn;
11127        try {
11128            conn = (ContentProviderConnection)connection;
11129        } catch (ClassCastException e) {
11130            String msg ="refContentProvider: " + connection
11131                    + " not a ContentProviderConnection";
11132            Slog.w(TAG, msg);
11133            throw new IllegalArgumentException(msg);
11134        }
11135        if (conn == null) {
11136            throw new NullPointerException("connection is null");
11137        }
11138
11139        synchronized (this) {
11140            if (stable > 0) {
11141                conn.numStableIncs += stable;
11142            }
11143            stable = conn.stableCount + stable;
11144            if (stable < 0) {
11145                throw new IllegalStateException("stableCount < 0: " + stable);
11146            }
11147
11148            if (unstable > 0) {
11149                conn.numUnstableIncs += unstable;
11150            }
11151            unstable = conn.unstableCount + unstable;
11152            if (unstable < 0) {
11153                throw new IllegalStateException("unstableCount < 0: " + unstable);
11154            }
11155
11156            if ((stable+unstable) <= 0) {
11157                throw new IllegalStateException("ref counts can't go to zero here: stable="
11158                        + stable + " unstable=" + unstable);
11159            }
11160            conn.stableCount = stable;
11161            conn.unstableCount = unstable;
11162            return !conn.dead;
11163        }
11164    }
11165
11166    public void unstableProviderDied(IBinder connection) {
11167        ContentProviderConnection conn;
11168        try {
11169            conn = (ContentProviderConnection)connection;
11170        } catch (ClassCastException e) {
11171            String msg ="refContentProvider: " + connection
11172                    + " not a ContentProviderConnection";
11173            Slog.w(TAG, msg);
11174            throw new IllegalArgumentException(msg);
11175        }
11176        if (conn == null) {
11177            throw new NullPointerException("connection is null");
11178        }
11179
11180        // Safely retrieve the content provider associated with the connection.
11181        IContentProvider provider;
11182        synchronized (this) {
11183            provider = conn.provider.provider;
11184        }
11185
11186        if (provider == null) {
11187            // Um, yeah, we're way ahead of you.
11188            return;
11189        }
11190
11191        // Make sure the caller is being honest with us.
11192        if (provider.asBinder().pingBinder()) {
11193            // Er, no, still looks good to us.
11194            synchronized (this) {
11195                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11196                        + " says " + conn + " died, but we don't agree");
11197                return;
11198            }
11199        }
11200
11201        // Well look at that!  It's dead!
11202        synchronized (this) {
11203            if (conn.provider.provider != provider) {
11204                // But something changed...  good enough.
11205                return;
11206            }
11207
11208            ProcessRecord proc = conn.provider.proc;
11209            if (proc == null || proc.thread == null) {
11210                // Seems like the process is already cleaned up.
11211                return;
11212            }
11213
11214            // As far as we're concerned, this is just like receiving a
11215            // death notification...  just a bit prematurely.
11216            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11217                    + ") early provider death");
11218            final long ident = Binder.clearCallingIdentity();
11219            try {
11220                appDiedLocked(proc);
11221            } finally {
11222                Binder.restoreCallingIdentity(ident);
11223            }
11224        }
11225    }
11226
11227    @Override
11228    public void appNotRespondingViaProvider(IBinder connection) {
11229        enforceCallingPermission(
11230                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11231
11232        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11233        if (conn == null) {
11234            Slog.w(TAG, "ContentProviderConnection is null");
11235            return;
11236        }
11237
11238        final ProcessRecord host = conn.provider.proc;
11239        if (host == null) {
11240            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11241            return;
11242        }
11243
11244        mHandler.post(new Runnable() {
11245            @Override
11246            public void run() {
11247                mAppErrors.appNotResponding(host, null, null, false,
11248                        "ContentProvider not responding");
11249            }
11250        });
11251    }
11252
11253    public final void installSystemProviders() {
11254        List<ProviderInfo> providers;
11255        synchronized (this) {
11256            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11257            providers = generateApplicationProvidersLocked(app);
11258            if (providers != null) {
11259                for (int i=providers.size()-1; i>=0; i--) {
11260                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11261                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11262                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11263                                + ": not system .apk");
11264                        providers.remove(i);
11265                    }
11266                }
11267            }
11268        }
11269        if (providers != null) {
11270            mSystemThread.installSystemProviders(providers);
11271        }
11272
11273        mCoreSettingsObserver = new CoreSettingsObserver(this);
11274        mFontScaleSettingObserver = new FontScaleSettingObserver();
11275
11276        //mUsageStatsService.monitorPackages();
11277    }
11278
11279    private void startPersistentApps(int matchFlags) {
11280        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11281
11282        synchronized (this) {
11283            try {
11284                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11285                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11286                for (ApplicationInfo app : apps) {
11287                    if (!"android".equals(app.packageName)) {
11288                        addAppLocked(app, false, null /* ABI override */);
11289                    }
11290                }
11291            } catch (RemoteException ex) {
11292            }
11293        }
11294    }
11295
11296    /**
11297     * When a user is unlocked, we need to install encryption-unaware providers
11298     * belonging to any running apps.
11299     */
11300    private void installEncryptionUnawareProviders(int userId) {
11301        // We're only interested in providers that are encryption unaware, and
11302        // we don't care about uninstalled apps, since there's no way they're
11303        // running at this point.
11304        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11305
11306        synchronized (this) {
11307            final int NP = mProcessNames.getMap().size();
11308            for (int ip = 0; ip < NP; ip++) {
11309                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11310                final int NA = apps.size();
11311                for (int ia = 0; ia < NA; ia++) {
11312                    final ProcessRecord app = apps.valueAt(ia);
11313                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11314
11315                    final int NG = app.pkgList.size();
11316                    for (int ig = 0; ig < NG; ig++) {
11317                        try {
11318                            final String pkgName = app.pkgList.keyAt(ig);
11319                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11320                                    .getPackageInfo(pkgName, matchFlags, userId);
11321                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11322                                for (ProviderInfo pi : pkgInfo.providers) {
11323                                    // TODO: keep in sync with generateApplicationProvidersLocked
11324                                    final boolean processMatch = Objects.equals(pi.processName,
11325                                            app.processName) || pi.multiprocess;
11326                                    final boolean userMatch = isSingleton(pi.processName,
11327                                            pi.applicationInfo, pi.name, pi.flags)
11328                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11329                                    if (processMatch && userMatch) {
11330                                        Log.v(TAG, "Installing " + pi);
11331                                        app.thread.scheduleInstallProvider(pi);
11332                                    } else {
11333                                        Log.v(TAG, "Skipping " + pi);
11334                                    }
11335                                }
11336                            }
11337                        } catch (RemoteException ignored) {
11338                        }
11339                    }
11340                }
11341            }
11342        }
11343    }
11344
11345    /**
11346     * Allows apps to retrieve the MIME type of a URI.
11347     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11348     * users, then it does not need permission to access the ContentProvider.
11349     * Either, it needs cross-user uri grants.
11350     *
11351     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11352     *
11353     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11354     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11355     */
11356    public String getProviderMimeType(Uri uri, int userId) {
11357        enforceNotIsolatedCaller("getProviderMimeType");
11358        final String name = uri.getAuthority();
11359        int callingUid = Binder.getCallingUid();
11360        int callingPid = Binder.getCallingPid();
11361        long ident = 0;
11362        boolean clearedIdentity = false;
11363        synchronized (this) {
11364            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11365        }
11366        if (canClearIdentity(callingPid, callingUid, userId)) {
11367            clearedIdentity = true;
11368            ident = Binder.clearCallingIdentity();
11369        }
11370        ContentProviderHolder holder = null;
11371        try {
11372            holder = getContentProviderExternalUnchecked(name, null, userId);
11373            if (holder != null) {
11374                return holder.provider.getType(uri);
11375            }
11376        } catch (RemoteException e) {
11377            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11378            return null;
11379        } catch (Exception e) {
11380            Log.w(TAG, "Exception while determining type of " + uri, e);
11381            return null;
11382        } finally {
11383            // We need to clear the identity to call removeContentProviderExternalUnchecked
11384            if (!clearedIdentity) {
11385                ident = Binder.clearCallingIdentity();
11386            }
11387            try {
11388                if (holder != null) {
11389                    removeContentProviderExternalUnchecked(name, null, userId);
11390                }
11391            } finally {
11392                Binder.restoreCallingIdentity(ident);
11393            }
11394        }
11395
11396        return null;
11397    }
11398
11399    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11400        if (UserHandle.getUserId(callingUid) == userId) {
11401            return true;
11402        }
11403        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11404                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11405                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11406                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11407                return true;
11408        }
11409        return false;
11410    }
11411
11412    // =========================================================
11413    // GLOBAL MANAGEMENT
11414    // =========================================================
11415
11416    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11417            boolean isolated, int isolatedUid) {
11418        String proc = customProcess != null ? customProcess : info.processName;
11419        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11420        final int userId = UserHandle.getUserId(info.uid);
11421        int uid = info.uid;
11422        if (isolated) {
11423            if (isolatedUid == 0) {
11424                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11425                while (true) {
11426                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11427                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11428                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11429                    }
11430                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11431                    mNextIsolatedProcessUid++;
11432                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11433                        // No process for this uid, use it.
11434                        break;
11435                    }
11436                    stepsLeft--;
11437                    if (stepsLeft <= 0) {
11438                        return null;
11439                    }
11440                }
11441            } else {
11442                // Special case for startIsolatedProcess (internal only), where
11443                // the uid of the isolated process is specified by the caller.
11444                uid = isolatedUid;
11445            }
11446        }
11447        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11448        if (!mBooted && !mBooting
11449                && userId == UserHandle.USER_SYSTEM
11450                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11451            r.persistent = true;
11452        }
11453        addProcessNameLocked(r);
11454        return r;
11455    }
11456
11457    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11458            String abiOverride) {
11459        ProcessRecord app;
11460        if (!isolated) {
11461            app = getProcessRecordLocked(info.processName, info.uid, true);
11462        } else {
11463            app = null;
11464        }
11465
11466        if (app == null) {
11467            app = newProcessRecordLocked(info, null, isolated, 0);
11468            updateLruProcessLocked(app, false, null);
11469            updateOomAdjLocked();
11470        }
11471
11472        // This package really, really can not be stopped.
11473        try {
11474            AppGlobals.getPackageManager().setPackageStoppedState(
11475                    info.packageName, false, UserHandle.getUserId(app.uid));
11476        } catch (RemoteException e) {
11477        } catch (IllegalArgumentException e) {
11478            Slog.w(TAG, "Failed trying to unstop package "
11479                    + info.packageName + ": " + e);
11480        }
11481
11482        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11483            app.persistent = true;
11484            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11485        }
11486        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11487            mPersistentStartingProcesses.add(app);
11488            startProcessLocked(app, "added application", app.processName, abiOverride,
11489                    null /* entryPoint */, null /* entryPointArgs */);
11490        }
11491
11492        return app;
11493    }
11494
11495    public void unhandledBack() {
11496        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11497                "unhandledBack()");
11498
11499        synchronized(this) {
11500            final long origId = Binder.clearCallingIdentity();
11501            try {
11502                getFocusedStack().unhandledBackLocked();
11503            } finally {
11504                Binder.restoreCallingIdentity(origId);
11505            }
11506        }
11507    }
11508
11509    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11510        enforceNotIsolatedCaller("openContentUri");
11511        final int userId = UserHandle.getCallingUserId();
11512        String name = uri.getAuthority();
11513        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11514        ParcelFileDescriptor pfd = null;
11515        if (cph != null) {
11516            // We record the binder invoker's uid in thread-local storage before
11517            // going to the content provider to open the file.  Later, in the code
11518            // that handles all permissions checks, we look for this uid and use
11519            // that rather than the Activity Manager's own uid.  The effect is that
11520            // we do the check against the caller's permissions even though it looks
11521            // to the content provider like the Activity Manager itself is making
11522            // the request.
11523            Binder token = new Binder();
11524            sCallerIdentity.set(new Identity(
11525                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11526            try {
11527                pfd = cph.provider.openFile(null, uri, "r", null, token);
11528            } catch (FileNotFoundException e) {
11529                // do nothing; pfd will be returned null
11530            } finally {
11531                // Ensure that whatever happens, we clean up the identity state
11532                sCallerIdentity.remove();
11533                // Ensure we're done with the provider.
11534                removeContentProviderExternalUnchecked(name, null, userId);
11535            }
11536        } else {
11537            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11538        }
11539        return pfd;
11540    }
11541
11542    // Actually is sleeping or shutting down or whatever else in the future
11543    // is an inactive state.
11544    boolean isSleepingOrShuttingDownLocked() {
11545        return isSleepingLocked() || mShuttingDown;
11546    }
11547
11548    boolean isShuttingDownLocked() {
11549        return mShuttingDown;
11550    }
11551
11552    boolean isSleepingLocked() {
11553        return mSleeping;
11554    }
11555
11556    void onWakefulnessChanged(int wakefulness) {
11557        synchronized(this) {
11558            mWakefulness = wakefulness;
11559            updateSleepIfNeededLocked();
11560        }
11561    }
11562
11563    void finishRunningVoiceLocked() {
11564        if (mRunningVoice != null) {
11565            mRunningVoice = null;
11566            mVoiceWakeLock.release();
11567            updateSleepIfNeededLocked();
11568        }
11569    }
11570
11571    void startTimeTrackingFocusedActivityLocked() {
11572        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11573            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11574        }
11575    }
11576
11577    void updateSleepIfNeededLocked() {
11578        if (mSleeping && !shouldSleepLocked()) {
11579            mSleeping = false;
11580            startTimeTrackingFocusedActivityLocked();
11581            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11582            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11583            updateOomAdjLocked();
11584        } else if (!mSleeping && shouldSleepLocked()) {
11585            mSleeping = true;
11586            if (mCurAppTimeTracker != null) {
11587                mCurAppTimeTracker.stop();
11588            }
11589            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11590            mStackSupervisor.goingToSleepLocked();
11591            updateOomAdjLocked();
11592
11593            // Initialize the wake times of all processes.
11594            checkExcessivePowerUsageLocked(false);
11595            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11596            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11597            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11598        }
11599    }
11600
11601    private boolean shouldSleepLocked() {
11602        // Resume applications while running a voice interactor.
11603        if (mRunningVoice != null) {
11604            return false;
11605        }
11606
11607        // TODO: Transform the lock screen state into a sleep token instead.
11608        switch (mWakefulness) {
11609            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11610            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11611            case PowerManagerInternal.WAKEFULNESS_DOZING:
11612                // Pause applications whenever the lock screen is shown or any sleep
11613                // tokens have been acquired.
11614                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11615            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11616            default:
11617                // If we're asleep then pause applications unconditionally.
11618                return true;
11619        }
11620    }
11621
11622    /** Pokes the task persister. */
11623    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11624        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11625    }
11626
11627    /** Notifies all listeners when the task stack has changed. */
11628    void notifyTaskStackChangedLocked() {
11629        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11630        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11631        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11632        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11633    }
11634
11635    /** Notifies all listeners when an Activity is pinned. */
11636    void notifyActivityPinnedLocked() {
11637        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11638        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11639    }
11640
11641    /**
11642     * Notifies all listeners when an attempt was made to start an an activity that is already
11643     * running in the pinned stack and the activity was not actually started, but the task is
11644     * either brought to the front or a new Intent is delivered to it.
11645     */
11646    void notifyPinnedActivityRestartAttemptLocked() {
11647        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11648        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11649    }
11650
11651    /** Notifies all listeners when the pinned stack animation ends. */
11652    @Override
11653    public void notifyPinnedStackAnimationEnded() {
11654        synchronized (this) {
11655            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11656            mHandler.obtainMessage(
11657                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11658        }
11659    }
11660
11661    @Override
11662    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11663        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11664    }
11665
11666    @Override
11667    public boolean shutdown(int timeout) {
11668        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11669                != PackageManager.PERMISSION_GRANTED) {
11670            throw new SecurityException("Requires permission "
11671                    + android.Manifest.permission.SHUTDOWN);
11672        }
11673
11674        boolean timedout = false;
11675
11676        synchronized(this) {
11677            mShuttingDown = true;
11678            updateEventDispatchingLocked();
11679            timedout = mStackSupervisor.shutdownLocked(timeout);
11680        }
11681
11682        mAppOpsService.shutdown();
11683        if (mUsageStatsService != null) {
11684            mUsageStatsService.prepareShutdown();
11685        }
11686        mBatteryStatsService.shutdown();
11687        synchronized (this) {
11688            mProcessStats.shutdownLocked();
11689            notifyTaskPersisterLocked(null, true);
11690        }
11691
11692        return timedout;
11693    }
11694
11695    public final void activitySlept(IBinder token) {
11696        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11697
11698        final long origId = Binder.clearCallingIdentity();
11699
11700        synchronized (this) {
11701            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11702            if (r != null) {
11703                mStackSupervisor.activitySleptLocked(r);
11704            }
11705        }
11706
11707        Binder.restoreCallingIdentity(origId);
11708    }
11709
11710    private String lockScreenShownToString() {
11711        switch (mLockScreenShown) {
11712            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11713            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11714            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11715            default: return "Unknown=" + mLockScreenShown;
11716        }
11717    }
11718
11719    void logLockScreen(String msg) {
11720        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11721                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11722                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11723                + " mSleeping=" + mSleeping);
11724    }
11725
11726    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11727        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11728        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11729        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11730            boolean wasRunningVoice = mRunningVoice != null;
11731            mRunningVoice = session;
11732            if (!wasRunningVoice) {
11733                mVoiceWakeLock.acquire();
11734                updateSleepIfNeededLocked();
11735            }
11736        }
11737    }
11738
11739    private void updateEventDispatchingLocked() {
11740        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11741    }
11742
11743    public void setLockScreenShown(boolean showing, boolean occluded) {
11744        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11745                != PackageManager.PERMISSION_GRANTED) {
11746            throw new SecurityException("Requires permission "
11747                    + android.Manifest.permission.DEVICE_POWER);
11748        }
11749
11750        synchronized(this) {
11751            long ident = Binder.clearCallingIdentity();
11752            try {
11753                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11754                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11755                if (showing && occluded) {
11756                    // The lock screen is currently showing, but is occluded by a window that can
11757                    // show on top of the lock screen. In this can we want to dismiss the docked
11758                    // stack since it will be complicated/risky to try to put the activity on top
11759                    // of the lock screen in the right fullscreen configuration.
11760                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11761                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11762                }
11763
11764                updateSleepIfNeededLocked();
11765            } finally {
11766                Binder.restoreCallingIdentity(ident);
11767            }
11768        }
11769    }
11770
11771    @Override
11772    public void notifyLockedProfile(@UserIdInt int userId) {
11773        try {
11774            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11775                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11776            }
11777        } catch (RemoteException ex) {
11778            throw new SecurityException("Fail to check is caller a privileged app", ex);
11779        }
11780
11781        synchronized (this) {
11782            if (mStackSupervisor.isUserLockedProfile(userId)) {
11783                final long ident = Binder.clearCallingIdentity();
11784                try {
11785                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11786                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11787                        // If there is no device lock, we will show the profile's credential page.
11788                        mActivityStarter.showConfirmDeviceCredential(userId);
11789                    } else {
11790                        // Showing launcher to avoid user entering credential twice.
11791                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11792                    }
11793                } finally {
11794                    Binder.restoreCallingIdentity(ident);
11795                }
11796            }
11797        }
11798    }
11799
11800    @Override
11801    public void startConfirmDeviceCredentialIntent(Intent intent) {
11802        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11803        synchronized (this) {
11804            final long ident = Binder.clearCallingIdentity();
11805            try {
11806                mActivityStarter.startConfirmCredentialIntent(intent);
11807            } finally {
11808                Binder.restoreCallingIdentity(ident);
11809            }
11810        }
11811    }
11812
11813    @Override
11814    public void stopAppSwitches() {
11815        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11816                != PackageManager.PERMISSION_GRANTED) {
11817            throw new SecurityException("viewquires permission "
11818                    + android.Manifest.permission.STOP_APP_SWITCHES);
11819        }
11820
11821        synchronized(this) {
11822            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11823                    + APP_SWITCH_DELAY_TIME;
11824            mDidAppSwitch = false;
11825            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11826            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11827            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11828        }
11829    }
11830
11831    public void resumeAppSwitches() {
11832        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11833                != PackageManager.PERMISSION_GRANTED) {
11834            throw new SecurityException("Requires permission "
11835                    + android.Manifest.permission.STOP_APP_SWITCHES);
11836        }
11837
11838        synchronized(this) {
11839            // Note that we don't execute any pending app switches... we will
11840            // let those wait until either the timeout, or the next start
11841            // activity request.
11842            mAppSwitchesAllowedTime = 0;
11843        }
11844    }
11845
11846    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11847            int callingPid, int callingUid, String name) {
11848        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11849            return true;
11850        }
11851
11852        int perm = checkComponentPermission(
11853                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11854                sourceUid, -1, true);
11855        if (perm == PackageManager.PERMISSION_GRANTED) {
11856            return true;
11857        }
11858
11859        // If the actual IPC caller is different from the logical source, then
11860        // also see if they are allowed to control app switches.
11861        if (callingUid != -1 && callingUid != sourceUid) {
11862            perm = checkComponentPermission(
11863                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11864                    callingUid, -1, true);
11865            if (perm == PackageManager.PERMISSION_GRANTED) {
11866                return true;
11867            }
11868        }
11869
11870        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11871        return false;
11872    }
11873
11874    public void setDebugApp(String packageName, boolean waitForDebugger,
11875            boolean persistent) {
11876        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11877                "setDebugApp()");
11878
11879        long ident = Binder.clearCallingIdentity();
11880        try {
11881            // Note that this is not really thread safe if there are multiple
11882            // callers into it at the same time, but that's not a situation we
11883            // care about.
11884            if (persistent) {
11885                final ContentResolver resolver = mContext.getContentResolver();
11886                Settings.Global.putString(
11887                    resolver, Settings.Global.DEBUG_APP,
11888                    packageName);
11889                Settings.Global.putInt(
11890                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11891                    waitForDebugger ? 1 : 0);
11892            }
11893
11894            synchronized (this) {
11895                if (!persistent) {
11896                    mOrigDebugApp = mDebugApp;
11897                    mOrigWaitForDebugger = mWaitForDebugger;
11898                }
11899                mDebugApp = packageName;
11900                mWaitForDebugger = waitForDebugger;
11901                mDebugTransient = !persistent;
11902                if (packageName != null) {
11903                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11904                            false, UserHandle.USER_ALL, "set debug app");
11905                }
11906            }
11907        } finally {
11908            Binder.restoreCallingIdentity(ident);
11909        }
11910    }
11911
11912    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11913        synchronized (this) {
11914            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11915            if (!isDebuggable) {
11916                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11917                    throw new SecurityException("Process not debuggable: " + app.packageName);
11918                }
11919            }
11920
11921            mTrackAllocationApp = processName;
11922        }
11923    }
11924
11925    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11926        synchronized (this) {
11927            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11928            if (!isDebuggable) {
11929                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11930                    throw new SecurityException("Process not debuggable: " + app.packageName);
11931                }
11932            }
11933            mProfileApp = processName;
11934            mProfileFile = profilerInfo.profileFile;
11935            if (mProfileFd != null) {
11936                try {
11937                    mProfileFd.close();
11938                } catch (IOException e) {
11939                }
11940                mProfileFd = null;
11941            }
11942            mProfileFd = profilerInfo.profileFd;
11943            mSamplingInterval = profilerInfo.samplingInterval;
11944            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11945            mProfileType = 0;
11946        }
11947    }
11948
11949    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11950        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11951        if (!isDebuggable) {
11952            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11953                throw new SecurityException("Process not debuggable: " + app.packageName);
11954            }
11955        }
11956        mNativeDebuggingApp = processName;
11957    }
11958
11959    @Override
11960    public void setAlwaysFinish(boolean enabled) {
11961        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11962                "setAlwaysFinish()");
11963
11964        long ident = Binder.clearCallingIdentity();
11965        try {
11966            Settings.Global.putInt(
11967                    mContext.getContentResolver(),
11968                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11969
11970            synchronized (this) {
11971                mAlwaysFinishActivities = enabled;
11972            }
11973        } finally {
11974            Binder.restoreCallingIdentity(ident);
11975        }
11976    }
11977
11978    @Override
11979    public void setLenientBackgroundCheck(boolean enabled) {
11980        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11981                "setLenientBackgroundCheck()");
11982
11983        long ident = Binder.clearCallingIdentity();
11984        try {
11985            Settings.Global.putInt(
11986                    mContext.getContentResolver(),
11987                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11988
11989            synchronized (this) {
11990                mLenientBackgroundCheck = enabled;
11991            }
11992        } finally {
11993            Binder.restoreCallingIdentity(ident);
11994        }
11995    }
11996
11997    @Override
11998    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11999        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12000                "setActivityController()");
12001        synchronized (this) {
12002            mController = controller;
12003            mControllerIsAMonkey = imAMonkey;
12004            Watchdog.getInstance().setActivityController(controller);
12005        }
12006    }
12007
12008    @Override
12009    public void setUserIsMonkey(boolean userIsMonkey) {
12010        synchronized (this) {
12011            synchronized (mPidsSelfLocked) {
12012                final int callingPid = Binder.getCallingPid();
12013                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12014                if (precessRecord == null) {
12015                    throw new SecurityException("Unknown process: " + callingPid);
12016                }
12017                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12018                    throw new SecurityException("Only an instrumentation process "
12019                            + "with a UiAutomation can call setUserIsMonkey");
12020                }
12021            }
12022            mUserIsMonkey = userIsMonkey;
12023        }
12024    }
12025
12026    @Override
12027    public boolean isUserAMonkey() {
12028        synchronized (this) {
12029            // If there is a controller also implies the user is a monkey.
12030            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12031        }
12032    }
12033
12034    public void requestBugReport(int bugreportType) {
12035        String service = null;
12036        switch (bugreportType) {
12037            case ActivityManager.BUGREPORT_OPTION_FULL:
12038                service = "bugreport";
12039                break;
12040            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12041                service = "bugreportplus";
12042                break;
12043            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12044                service = "bugreportremote";
12045                break;
12046        }
12047        if (service == null) {
12048            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12049                    + bugreportType);
12050        }
12051        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12052        SystemProperties.set("ctl.start", service);
12053    }
12054
12055    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12056        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12057    }
12058
12059    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12060        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12061            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12062        }
12063        return KEY_DISPATCHING_TIMEOUT;
12064    }
12065
12066    @Override
12067    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12068        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12069                != PackageManager.PERMISSION_GRANTED) {
12070            throw new SecurityException("Requires permission "
12071                    + android.Manifest.permission.FILTER_EVENTS);
12072        }
12073        ProcessRecord proc;
12074        long timeout;
12075        synchronized (this) {
12076            synchronized (mPidsSelfLocked) {
12077                proc = mPidsSelfLocked.get(pid);
12078            }
12079            timeout = getInputDispatchingTimeoutLocked(proc);
12080        }
12081
12082        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12083            return -1;
12084        }
12085
12086        return timeout;
12087    }
12088
12089    /**
12090     * Handle input dispatching timeouts.
12091     * Returns whether input dispatching should be aborted or not.
12092     */
12093    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12094            final ActivityRecord activity, final ActivityRecord parent,
12095            final boolean aboveSystem, String reason) {
12096        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12097                != PackageManager.PERMISSION_GRANTED) {
12098            throw new SecurityException("Requires permission "
12099                    + android.Manifest.permission.FILTER_EVENTS);
12100        }
12101
12102        final String annotation;
12103        if (reason == null) {
12104            annotation = "Input dispatching timed out";
12105        } else {
12106            annotation = "Input dispatching timed out (" + reason + ")";
12107        }
12108
12109        if (proc != null) {
12110            synchronized (this) {
12111                if (proc.debugging) {
12112                    return false;
12113                }
12114
12115                if (mDidDexOpt) {
12116                    // Give more time since we were dexopting.
12117                    mDidDexOpt = false;
12118                    return false;
12119                }
12120
12121                if (proc.instrumentationClass != null) {
12122                    Bundle info = new Bundle();
12123                    info.putString("shortMsg", "keyDispatchingTimedOut");
12124                    info.putString("longMsg", annotation);
12125                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12126                    return true;
12127                }
12128            }
12129            mHandler.post(new Runnable() {
12130                @Override
12131                public void run() {
12132                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12133                }
12134            });
12135        }
12136
12137        return true;
12138    }
12139
12140    @Override
12141    public Bundle getAssistContextExtras(int requestType) {
12142        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12143                null, null, true /* focused */, true /* newSessionId */,
12144                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12145        if (pae == null) {
12146            return null;
12147        }
12148        synchronized (pae) {
12149            while (!pae.haveResult) {
12150                try {
12151                    pae.wait();
12152                } catch (InterruptedException e) {
12153                }
12154            }
12155        }
12156        synchronized (this) {
12157            buildAssistBundleLocked(pae, pae.result);
12158            mPendingAssistExtras.remove(pae);
12159            mUiHandler.removeCallbacks(pae);
12160        }
12161        return pae.extras;
12162    }
12163
12164    @Override
12165    public boolean isAssistDataAllowedOnCurrentActivity() {
12166        int userId;
12167        synchronized (this) {
12168            userId = mUserController.getCurrentUserIdLocked();
12169            ActivityRecord activity = getFocusedStack().topActivity();
12170            if (activity == null) {
12171                return false;
12172            }
12173            userId = activity.userId;
12174        }
12175        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12176                Context.DEVICE_POLICY_SERVICE);
12177        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12178    }
12179
12180    @Override
12181    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12182        long ident = Binder.clearCallingIdentity();
12183        try {
12184            synchronized (this) {
12185                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12186                ActivityRecord top = getFocusedStack().topActivity();
12187                if (top != caller) {
12188                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12189                            + " is not current top " + top);
12190                    return false;
12191                }
12192                if (!top.nowVisible) {
12193                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12194                            + " is not visible");
12195                    return false;
12196                }
12197            }
12198            AssistUtils utils = new AssistUtils(mContext);
12199            return utils.showSessionForActiveService(args,
12200                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12201        } finally {
12202            Binder.restoreCallingIdentity(ident);
12203        }
12204    }
12205
12206    @Override
12207    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12208            Bundle receiverExtras,
12209            IBinder activityToken, boolean focused, boolean newSessionId) {
12210        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12211                activityToken, focused, newSessionId,
12212                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12213                != null;
12214    }
12215
12216    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12217            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12218            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12219        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12220                "enqueueAssistContext()");
12221        synchronized (this) {
12222            ActivityRecord activity = getFocusedStack().topActivity();
12223            if (activity == null) {
12224                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12225                return null;
12226            }
12227            if (activity.app == null || activity.app.thread == null) {
12228                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12229                return null;
12230            }
12231            if (focused) {
12232                if (activityToken != null) {
12233                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12234                    if (activity != caller) {
12235                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12236                                + " is not current top " + activity);
12237                        return null;
12238                    }
12239                }
12240            } else {
12241                activity = ActivityRecord.forTokenLocked(activityToken);
12242                if (activity == null) {
12243                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12244                            + " couldn't be found");
12245                    return null;
12246                }
12247            }
12248
12249            PendingAssistExtras pae;
12250            Bundle extras = new Bundle();
12251            if (args != null) {
12252                extras.putAll(args);
12253            }
12254            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12255            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12256            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12257                    userHandle);
12258            // Increment the sessionId if necessary
12259            if (newSessionId) {
12260                mViSessionId++;
12261            }
12262            try {
12263                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12264                        requestType, mViSessionId);
12265                mPendingAssistExtras.add(pae);
12266                mUiHandler.postDelayed(pae, timeout);
12267            } catch (RemoteException e) {
12268                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12269                return null;
12270            }
12271            return pae;
12272        }
12273    }
12274
12275    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12276        IResultReceiver receiver;
12277        synchronized (this) {
12278            mPendingAssistExtras.remove(pae);
12279            receiver = pae.receiver;
12280        }
12281        if (receiver != null) {
12282            // Caller wants result sent back to them.
12283            Bundle sendBundle = new Bundle();
12284            // At least return the receiver extras
12285            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12286                    pae.receiverExtras);
12287            try {
12288                pae.receiver.send(0, sendBundle);
12289            } catch (RemoteException e) {
12290            }
12291        }
12292    }
12293
12294    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12295        if (result != null) {
12296            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12297        }
12298        if (pae.hint != null) {
12299            pae.extras.putBoolean(pae.hint, true);
12300        }
12301    }
12302
12303    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12304            AssistContent content, Uri referrer) {
12305        PendingAssistExtras pae = (PendingAssistExtras)token;
12306        synchronized (pae) {
12307            pae.result = extras;
12308            pae.structure = structure;
12309            pae.content = content;
12310            if (referrer != null) {
12311                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12312            }
12313            pae.haveResult = true;
12314            pae.notifyAll();
12315            if (pae.intent == null && pae.receiver == null) {
12316                // Caller is just waiting for the result.
12317                return;
12318            }
12319        }
12320
12321        // We are now ready to launch the assist activity.
12322        IResultReceiver sendReceiver = null;
12323        Bundle sendBundle = null;
12324        synchronized (this) {
12325            buildAssistBundleLocked(pae, extras);
12326            boolean exists = mPendingAssistExtras.remove(pae);
12327            mUiHandler.removeCallbacks(pae);
12328            if (!exists) {
12329                // Timed out.
12330                return;
12331            }
12332            if ((sendReceiver=pae.receiver) != null) {
12333                // Caller wants result sent back to them.
12334                sendBundle = new Bundle();
12335                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12336                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12337                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12338                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12339                        pae.receiverExtras);
12340            }
12341        }
12342        if (sendReceiver != null) {
12343            try {
12344                sendReceiver.send(0, sendBundle);
12345            } catch (RemoteException e) {
12346            }
12347            return;
12348        }
12349
12350        long ident = Binder.clearCallingIdentity();
12351        try {
12352            pae.intent.replaceExtras(pae.extras);
12353            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12354                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12355                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12356            closeSystemDialogs("assist");
12357            try {
12358                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12359            } catch (ActivityNotFoundException e) {
12360                Slog.w(TAG, "No activity to handle assist action.", e);
12361            }
12362        } finally {
12363            Binder.restoreCallingIdentity(ident);
12364        }
12365    }
12366
12367    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12368            Bundle args) {
12369        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12370                true /* focused */, true /* newSessionId */,
12371                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12372    }
12373
12374    public void registerProcessObserver(IProcessObserver observer) {
12375        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12376                "registerProcessObserver()");
12377        synchronized (this) {
12378            mProcessObservers.register(observer);
12379        }
12380    }
12381
12382    @Override
12383    public void unregisterProcessObserver(IProcessObserver observer) {
12384        synchronized (this) {
12385            mProcessObservers.unregister(observer);
12386        }
12387    }
12388
12389    @Override
12390    public void registerUidObserver(IUidObserver observer, int which) {
12391        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12392                "registerUidObserver()");
12393        synchronized (this) {
12394            mUidObservers.register(observer, which);
12395        }
12396    }
12397
12398    @Override
12399    public void unregisterUidObserver(IUidObserver observer) {
12400        synchronized (this) {
12401            mUidObservers.unregister(observer);
12402        }
12403    }
12404
12405    @Override
12406    public boolean convertFromTranslucent(IBinder token) {
12407        final long origId = Binder.clearCallingIdentity();
12408        try {
12409            synchronized (this) {
12410                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12411                if (r == null) {
12412                    return false;
12413                }
12414                final boolean translucentChanged = r.changeWindowTranslucency(true);
12415                if (translucentChanged) {
12416                    r.task.stack.releaseBackgroundResources(r);
12417                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12418                }
12419                mWindowManager.setAppFullscreen(token, true);
12420                return translucentChanged;
12421            }
12422        } finally {
12423            Binder.restoreCallingIdentity(origId);
12424        }
12425    }
12426
12427    @Override
12428    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12429        final long origId = Binder.clearCallingIdentity();
12430        try {
12431            synchronized (this) {
12432                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12433                if (r == null) {
12434                    return false;
12435                }
12436                int index = r.task.mActivities.lastIndexOf(r);
12437                if (index > 0) {
12438                    ActivityRecord under = r.task.mActivities.get(index - 1);
12439                    under.returningOptions = options;
12440                }
12441                final boolean translucentChanged = r.changeWindowTranslucency(false);
12442                if (translucentChanged) {
12443                    r.task.stack.convertActivityToTranslucent(r);
12444                }
12445                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12446                mWindowManager.setAppFullscreen(token, false);
12447                return translucentChanged;
12448            }
12449        } finally {
12450            Binder.restoreCallingIdentity(origId);
12451        }
12452    }
12453
12454    @Override
12455    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12456        final long origId = Binder.clearCallingIdentity();
12457        try {
12458            synchronized (this) {
12459                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12460                if (r != null) {
12461                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12462                }
12463            }
12464            return false;
12465        } finally {
12466            Binder.restoreCallingIdentity(origId);
12467        }
12468    }
12469
12470    @Override
12471    public boolean isBackgroundVisibleBehind(IBinder token) {
12472        final long origId = Binder.clearCallingIdentity();
12473        try {
12474            synchronized (this) {
12475                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12476                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12477                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12478                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12479                return visible;
12480            }
12481        } finally {
12482            Binder.restoreCallingIdentity(origId);
12483        }
12484    }
12485
12486    @Override
12487    public ActivityOptions getActivityOptions(IBinder token) {
12488        final long origId = Binder.clearCallingIdentity();
12489        try {
12490            synchronized (this) {
12491                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12492                if (r != null) {
12493                    final ActivityOptions activityOptions = r.pendingOptions;
12494                    r.pendingOptions = null;
12495                    return activityOptions;
12496                }
12497                return null;
12498            }
12499        } finally {
12500            Binder.restoreCallingIdentity(origId);
12501        }
12502    }
12503
12504    @Override
12505    public void setImmersive(IBinder token, boolean immersive) {
12506        synchronized(this) {
12507            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12508            if (r == null) {
12509                throw new IllegalArgumentException();
12510            }
12511            r.immersive = immersive;
12512
12513            // update associated state if we're frontmost
12514            if (r == mFocusedActivity) {
12515                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12516                applyUpdateLockStateLocked(r);
12517            }
12518        }
12519    }
12520
12521    @Override
12522    public boolean isImmersive(IBinder token) {
12523        synchronized (this) {
12524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12525            if (r == null) {
12526                throw new IllegalArgumentException();
12527            }
12528            return r.immersive;
12529        }
12530    }
12531
12532    public void setVrThread(int tid) {
12533        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12534            throw new UnsupportedOperationException("VR mode not supported on this device!");
12535        }
12536
12537        synchronized (this) {
12538            ProcessRecord proc;
12539            synchronized (mPidsSelfLocked) {
12540                final int pid = Binder.getCallingPid();
12541                proc = mPidsSelfLocked.get(pid);
12542                if (proc != null && mInVrMode && tid >= 0) {
12543                    // ensure the tid belongs to the process
12544                    if (!Process.isThreadInProcess(pid, tid)) {
12545                        throw new IllegalArgumentException("VR thread does not belong to process");
12546                    }
12547                    // reset existing VR thread to CFS
12548                    if (proc.vrThreadTid != 0) {
12549                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12550                    }
12551                    // add check to guarantee that tid belongs to pid?
12552                    proc.vrThreadTid = tid;
12553                    // promote to FIFO now if the tid is non-zero
12554                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12555                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12556                    }
12557                } else {
12558                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12559                }
12560            }
12561        }
12562    }
12563
12564    @Override
12565    public void setRenderThread(int tid) {
12566        synchronized (this) {
12567            ProcessRecord proc;
12568            synchronized (mPidsSelfLocked) {
12569                int pid = Binder.getCallingPid();
12570                proc = mPidsSelfLocked.get(pid);
12571                if (mUseFifoUiScheduling && proc != null && proc.renderThreadTid == 0 && tid > 0) {
12572                    // ensure the tid belongs to the process
12573                    if (!Process.isThreadInProcess(pid, tid)) {
12574                        throw new IllegalArgumentException(
12575                            "Render thread does not belong to process");
12576                    }
12577                    proc.renderThreadTid = tid;
12578                    if (DEBUG_OOM_ADJ) {
12579                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12580                    }
12581                    // promote to FIFO now
12582                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12583                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12584                        Process.setThreadScheduler(proc.renderThreadTid,
12585                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12586                    }
12587                } else {
12588                    if (DEBUG_OOM_ADJ) {
12589                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12590                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12591                               mUseFifoUiScheduling);
12592                    }
12593                }
12594            }
12595        }
12596    }
12597
12598    @Override
12599    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12600        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12601            throw new UnsupportedOperationException("VR mode not supported on this device!");
12602        }
12603
12604        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12605
12606        ActivityRecord r;
12607        synchronized (this) {
12608            r = ActivityRecord.isInStackLocked(token);
12609        }
12610
12611        if (r == null) {
12612            throw new IllegalArgumentException();
12613        }
12614
12615        int err;
12616        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12617                VrManagerInternal.NO_ERROR) {
12618            return err;
12619        }
12620
12621        synchronized(this) {
12622            r.requestedVrComponent = (enabled) ? packageName : null;
12623
12624            // Update associated state if this activity is currently focused
12625            if (r == mFocusedActivity) {
12626                applyUpdateVrModeLocked(r);
12627            }
12628            return 0;
12629        }
12630    }
12631
12632    @Override
12633    public boolean isVrModePackageEnabled(ComponentName packageName) {
12634        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12635            throw new UnsupportedOperationException("VR mode not supported on this device!");
12636        }
12637
12638        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12639
12640        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12641                VrManagerInternal.NO_ERROR;
12642    }
12643
12644    public boolean isTopActivityImmersive() {
12645        enforceNotIsolatedCaller("startActivity");
12646        synchronized (this) {
12647            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12648            return (r != null) ? r.immersive : false;
12649        }
12650    }
12651
12652    @Override
12653    public boolean isTopOfTask(IBinder token) {
12654        synchronized (this) {
12655            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12656            if (r == null) {
12657                throw new IllegalArgumentException();
12658            }
12659            return r.task.getTopActivity() == r;
12660        }
12661    }
12662
12663    public final void enterSafeMode() {
12664        synchronized(this) {
12665            // It only makes sense to do this before the system is ready
12666            // and started launching other packages.
12667            if (!mSystemReady) {
12668                try {
12669                    AppGlobals.getPackageManager().enterSafeMode();
12670                } catch (RemoteException e) {
12671                }
12672            }
12673
12674            mSafeMode = true;
12675        }
12676    }
12677
12678    public final void showSafeModeOverlay() {
12679        View v = LayoutInflater.from(mContext).inflate(
12680                com.android.internal.R.layout.safe_mode, null);
12681        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12682        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12683        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12684        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12685        lp.gravity = Gravity.BOTTOM | Gravity.START;
12686        lp.format = v.getBackground().getOpacity();
12687        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12688                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12689        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12690        ((WindowManager)mContext.getSystemService(
12691                Context.WINDOW_SERVICE)).addView(v, lp);
12692    }
12693
12694    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12695        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12696            return;
12697        }
12698        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12699        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12700        synchronized (stats) {
12701            if (mBatteryStatsService.isOnBattery()) {
12702                mBatteryStatsService.enforceCallingPermission();
12703                int MY_UID = Binder.getCallingUid();
12704                final int uid;
12705                if (sender == null) {
12706                    uid = sourceUid;
12707                } else {
12708                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12709                }
12710                BatteryStatsImpl.Uid.Pkg pkg =
12711                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12712                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12713                pkg.noteWakeupAlarmLocked(tag);
12714            }
12715        }
12716    }
12717
12718    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12719        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12720            return;
12721        }
12722        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12723        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12724        synchronized (stats) {
12725            mBatteryStatsService.enforceCallingPermission();
12726            int MY_UID = Binder.getCallingUid();
12727            final int uid;
12728            if (sender == null) {
12729                uid = sourceUid;
12730            } else {
12731                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12732            }
12733            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12734        }
12735    }
12736
12737    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12738        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12739            return;
12740        }
12741        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12742        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12743        synchronized (stats) {
12744            mBatteryStatsService.enforceCallingPermission();
12745            int MY_UID = Binder.getCallingUid();
12746            final int uid;
12747            if (sender == null) {
12748                uid = sourceUid;
12749            } else {
12750                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12751            }
12752            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12753        }
12754    }
12755
12756    public boolean killPids(int[] pids, String pReason, boolean secure) {
12757        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12758            throw new SecurityException("killPids only available to the system");
12759        }
12760        String reason = (pReason == null) ? "Unknown" : pReason;
12761        // XXX Note: don't acquire main activity lock here, because the window
12762        // manager calls in with its locks held.
12763
12764        boolean killed = false;
12765        synchronized (mPidsSelfLocked) {
12766            int worstType = 0;
12767            for (int i=0; i<pids.length; i++) {
12768                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12769                if (proc != null) {
12770                    int type = proc.setAdj;
12771                    if (type > worstType) {
12772                        worstType = type;
12773                    }
12774                }
12775            }
12776
12777            // If the worst oom_adj is somewhere in the cached proc LRU range,
12778            // then constrain it so we will kill all cached procs.
12779            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12780                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12781                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12782            }
12783
12784            // If this is not a secure call, don't let it kill processes that
12785            // are important.
12786            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12787                worstType = ProcessList.SERVICE_ADJ;
12788            }
12789
12790            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12791            for (int i=0; i<pids.length; i++) {
12792                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12793                if (proc == null) {
12794                    continue;
12795                }
12796                int adj = proc.setAdj;
12797                if (adj >= worstType && !proc.killedByAm) {
12798                    proc.kill(reason, true);
12799                    killed = true;
12800                }
12801            }
12802        }
12803        return killed;
12804    }
12805
12806    @Override
12807    public void killUid(int appId, int userId, String reason) {
12808        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12809        synchronized (this) {
12810            final long identity = Binder.clearCallingIdentity();
12811            try {
12812                killPackageProcessesLocked(null, appId, userId,
12813                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12814                        reason != null ? reason : "kill uid");
12815            } finally {
12816                Binder.restoreCallingIdentity(identity);
12817            }
12818        }
12819    }
12820
12821    @Override
12822    public boolean killProcessesBelowForeground(String reason) {
12823        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12824            throw new SecurityException("killProcessesBelowForeground() only available to system");
12825        }
12826
12827        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12828    }
12829
12830    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12831        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12832            throw new SecurityException("killProcessesBelowAdj() only available to system");
12833        }
12834
12835        boolean killed = false;
12836        synchronized (mPidsSelfLocked) {
12837            final int size = mPidsSelfLocked.size();
12838            for (int i = 0; i < size; i++) {
12839                final int pid = mPidsSelfLocked.keyAt(i);
12840                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12841                if (proc == null) continue;
12842
12843                final int adj = proc.setAdj;
12844                if (adj > belowAdj && !proc.killedByAm) {
12845                    proc.kill(reason, true);
12846                    killed = true;
12847                }
12848            }
12849        }
12850        return killed;
12851    }
12852
12853    @Override
12854    public void hang(final IBinder who, boolean allowRestart) {
12855        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12856                != PackageManager.PERMISSION_GRANTED) {
12857            throw new SecurityException("Requires permission "
12858                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12859        }
12860
12861        final IBinder.DeathRecipient death = new DeathRecipient() {
12862            @Override
12863            public void binderDied() {
12864                synchronized (this) {
12865                    notifyAll();
12866                }
12867            }
12868        };
12869
12870        try {
12871            who.linkToDeath(death, 0);
12872        } catch (RemoteException e) {
12873            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12874            return;
12875        }
12876
12877        synchronized (this) {
12878            Watchdog.getInstance().setAllowRestart(allowRestart);
12879            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12880            synchronized (death) {
12881                while (who.isBinderAlive()) {
12882                    try {
12883                        death.wait();
12884                    } catch (InterruptedException e) {
12885                    }
12886                }
12887            }
12888            Watchdog.getInstance().setAllowRestart(true);
12889        }
12890    }
12891
12892    @Override
12893    public void restart() {
12894        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12895                != PackageManager.PERMISSION_GRANTED) {
12896            throw new SecurityException("Requires permission "
12897                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12898        }
12899
12900        Log.i(TAG, "Sending shutdown broadcast...");
12901
12902        BroadcastReceiver br = new BroadcastReceiver() {
12903            @Override public void onReceive(Context context, Intent intent) {
12904                // Now the broadcast is done, finish up the low-level shutdown.
12905                Log.i(TAG, "Shutting down activity manager...");
12906                shutdown(10000);
12907                Log.i(TAG, "Shutdown complete, restarting!");
12908                Process.killProcess(Process.myPid());
12909                System.exit(10);
12910            }
12911        };
12912
12913        // First send the high-level shut down broadcast.
12914        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12915        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12916        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12917        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12918        mContext.sendOrderedBroadcastAsUser(intent,
12919                UserHandle.ALL, null, br, mHandler, 0, null, null);
12920        */
12921        br.onReceive(mContext, intent);
12922    }
12923
12924    private long getLowRamTimeSinceIdle(long now) {
12925        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12926    }
12927
12928    @Override
12929    public void performIdleMaintenance() {
12930        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12931                != PackageManager.PERMISSION_GRANTED) {
12932            throw new SecurityException("Requires permission "
12933                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12934        }
12935
12936        synchronized (this) {
12937            final long now = SystemClock.uptimeMillis();
12938            final long timeSinceLastIdle = now - mLastIdleTime;
12939            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12940            mLastIdleTime = now;
12941            mLowRamTimeSinceLastIdle = 0;
12942            if (mLowRamStartTime != 0) {
12943                mLowRamStartTime = now;
12944            }
12945
12946            StringBuilder sb = new StringBuilder(128);
12947            sb.append("Idle maintenance over ");
12948            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12949            sb.append(" low RAM for ");
12950            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12951            Slog.i(TAG, sb.toString());
12952
12953            // If at least 1/3 of our time since the last idle period has been spent
12954            // with RAM low, then we want to kill processes.
12955            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12956
12957            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12958                ProcessRecord proc = mLruProcesses.get(i);
12959                if (proc.notCachedSinceIdle) {
12960                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12961                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12962                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12963                        if (doKilling && proc.initialIdlePss != 0
12964                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12965                            sb = new StringBuilder(128);
12966                            sb.append("Kill");
12967                            sb.append(proc.processName);
12968                            sb.append(" in idle maint: pss=");
12969                            sb.append(proc.lastPss);
12970                            sb.append(", swapPss=");
12971                            sb.append(proc.lastSwapPss);
12972                            sb.append(", initialPss=");
12973                            sb.append(proc.initialIdlePss);
12974                            sb.append(", period=");
12975                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12976                            sb.append(", lowRamPeriod=");
12977                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12978                            Slog.wtfQuiet(TAG, sb.toString());
12979                            proc.kill("idle maint (pss " + proc.lastPss
12980                                    + " from " + proc.initialIdlePss + ")", true);
12981                        }
12982                    }
12983                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12984                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12985                    proc.notCachedSinceIdle = true;
12986                    proc.initialIdlePss = 0;
12987                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12988                            mTestPssMode, isSleepingLocked(), now);
12989                }
12990            }
12991
12992            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12993            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12994        }
12995    }
12996
12997    @Override
12998    public void sendIdleJobTrigger() {
12999        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13000                != PackageManager.PERMISSION_GRANTED) {
13001            throw new SecurityException("Requires permission "
13002                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13003        }
13004
13005        final long ident = Binder.clearCallingIdentity();
13006        try {
13007            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13008                    .setPackage("android")
13009                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13010            broadcastIntent(null, intent, null, null, 0, null, null, null,
13011                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13012        } finally {
13013            Binder.restoreCallingIdentity(ident);
13014        }
13015    }
13016
13017    private void retrieveSettings() {
13018        final ContentResolver resolver = mContext.getContentResolver();
13019        final boolean freeformWindowManagement =
13020                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13021                        || Settings.Global.getInt(
13022                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13023        final boolean supportsPictureInPicture =
13024                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13025
13026        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13027        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13028        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13029        final boolean alwaysFinishActivities =
13030                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13031        final boolean lenientBackgroundCheck =
13032                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13033        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13034        final boolean forceResizable = Settings.Global.getInt(
13035                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13036        final boolean supportsLeanbackOnly =
13037                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13038
13039        // Transfer any global setting for forcing RTL layout, into a System Property
13040        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13041
13042        final Configuration configuration = new Configuration();
13043        Settings.System.getConfiguration(resolver, configuration);
13044        if (forceRtl) {
13045            // This will take care of setting the correct layout direction flags
13046            configuration.setLayoutDirection(configuration.locale);
13047        }
13048
13049        synchronized (this) {
13050            mDebugApp = mOrigDebugApp = debugApp;
13051            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13052            mAlwaysFinishActivities = alwaysFinishActivities;
13053            mLenientBackgroundCheck = lenientBackgroundCheck;
13054            mSupportsLeanbackOnly = supportsLeanbackOnly;
13055            mForceResizableActivities = forceResizable;
13056            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13057            if (supportsMultiWindow || forceResizable) {
13058                mSupportsMultiWindow = true;
13059                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13060                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13061            } else {
13062                mSupportsMultiWindow = false;
13063                mSupportsFreeformWindowManagement = false;
13064                mSupportsPictureInPicture = false;
13065            }
13066            // This happens before any activities are started, so we can
13067            // change mConfiguration in-place.
13068            updateConfigurationLocked(configuration, null, true);
13069            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13070                    "Initial config: " + mConfiguration);
13071
13072            // Load resources only after the current configuration has been set.
13073            final Resources res = mContext.getResources();
13074            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13075            mThumbnailWidth = res.getDimensionPixelSize(
13076                    com.android.internal.R.dimen.thumbnail_width);
13077            mThumbnailHeight = res.getDimensionPixelSize(
13078                    com.android.internal.R.dimen.thumbnail_height);
13079            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13080                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13081            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13082                    com.android.internal.R.string.config_appsNotReportingCrashes));
13083            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13084                mFullscreenThumbnailScale = (float) res
13085                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13086                    (float) mConfiguration.screenWidthDp;
13087            } else {
13088                mFullscreenThumbnailScale = res.getFraction(
13089                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13090            }
13091        }
13092    }
13093
13094    public boolean testIsSystemReady() {
13095        // no need to synchronize(this) just to read & return the value
13096        return mSystemReady;
13097    }
13098
13099    public void systemReady(final Runnable goingCallback) {
13100        synchronized(this) {
13101            if (mSystemReady) {
13102                // If we're done calling all the receivers, run the next "boot phase" passed in
13103                // by the SystemServer
13104                if (goingCallback != null) {
13105                    goingCallback.run();
13106                }
13107                return;
13108            }
13109
13110            mLocalDeviceIdleController
13111                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13112
13113            // Make sure we have the current profile info, since it is needed for security checks.
13114            mUserController.onSystemReady();
13115            mRecentTasks.onSystemReadyLocked();
13116            mAppOpsService.systemReady();
13117            mSystemReady = true;
13118        }
13119
13120        ArrayList<ProcessRecord> procsToKill = null;
13121        synchronized(mPidsSelfLocked) {
13122            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13123                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13124                if (!isAllowedWhileBooting(proc.info)){
13125                    if (procsToKill == null) {
13126                        procsToKill = new ArrayList<ProcessRecord>();
13127                    }
13128                    procsToKill.add(proc);
13129                }
13130            }
13131        }
13132
13133        synchronized(this) {
13134            if (procsToKill != null) {
13135                for (int i=procsToKill.size()-1; i>=0; i--) {
13136                    ProcessRecord proc = procsToKill.get(i);
13137                    Slog.i(TAG, "Removing system update proc: " + proc);
13138                    removeProcessLocked(proc, true, false, "system update done");
13139                }
13140            }
13141
13142            // Now that we have cleaned up any update processes, we
13143            // are ready to start launching real processes and know that
13144            // we won't trample on them any more.
13145            mProcessesReady = true;
13146        }
13147
13148        Slog.i(TAG, "System now ready");
13149        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13150            SystemClock.uptimeMillis());
13151
13152        synchronized(this) {
13153            // Make sure we have no pre-ready processes sitting around.
13154
13155            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13156                ResolveInfo ri = mContext.getPackageManager()
13157                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13158                                STOCK_PM_FLAGS);
13159                CharSequence errorMsg = null;
13160                if (ri != null) {
13161                    ActivityInfo ai = ri.activityInfo;
13162                    ApplicationInfo app = ai.applicationInfo;
13163                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13164                        mTopAction = Intent.ACTION_FACTORY_TEST;
13165                        mTopData = null;
13166                        mTopComponent = new ComponentName(app.packageName,
13167                                ai.name);
13168                    } else {
13169                        errorMsg = mContext.getResources().getText(
13170                                com.android.internal.R.string.factorytest_not_system);
13171                    }
13172                } else {
13173                    errorMsg = mContext.getResources().getText(
13174                            com.android.internal.R.string.factorytest_no_action);
13175                }
13176                if (errorMsg != null) {
13177                    mTopAction = null;
13178                    mTopData = null;
13179                    mTopComponent = null;
13180                    Message msg = Message.obtain();
13181                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13182                    msg.getData().putCharSequence("msg", errorMsg);
13183                    mUiHandler.sendMessage(msg);
13184                }
13185            }
13186        }
13187
13188        retrieveSettings();
13189        final int currentUserId;
13190        synchronized (this) {
13191            currentUserId = mUserController.getCurrentUserIdLocked();
13192            readGrantedUriPermissionsLocked();
13193        }
13194
13195        if (goingCallback != null) goingCallback.run();
13196
13197        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13198                Integer.toString(currentUserId), currentUserId);
13199        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13200                Integer.toString(currentUserId), currentUserId);
13201        mSystemServiceManager.startUser(currentUserId);
13202
13203        synchronized (this) {
13204            // Only start up encryption-aware persistent apps; once user is
13205            // unlocked we'll come back around and start unaware apps
13206            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13207
13208            // Start up initial activity.
13209            mBooting = true;
13210            // Enable home activity for system user, so that the system can always boot
13211            if (UserManager.isSplitSystemUser()) {
13212                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13213                try {
13214                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13215                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13216                            UserHandle.USER_SYSTEM);
13217                } catch (RemoteException e) {
13218                    throw e.rethrowAsRuntimeException();
13219                }
13220            }
13221            startHomeActivityLocked(currentUserId, "systemReady");
13222
13223            try {
13224                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13225                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13226                            + " data partition or your device will be unstable.");
13227                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13228                }
13229            } catch (RemoteException e) {
13230            }
13231
13232            if (!Build.isBuildConsistent()) {
13233                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13234                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13235            }
13236
13237            long ident = Binder.clearCallingIdentity();
13238            try {
13239                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13240                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13241                        | Intent.FLAG_RECEIVER_FOREGROUND);
13242                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13243                broadcastIntentLocked(null, null, intent,
13244                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13245                        null, false, false, MY_PID, Process.SYSTEM_UID,
13246                        currentUserId);
13247                intent = new Intent(Intent.ACTION_USER_STARTING);
13248                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13249                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13250                broadcastIntentLocked(null, null, intent,
13251                        null, new IIntentReceiver.Stub() {
13252                            @Override
13253                            public void performReceive(Intent intent, int resultCode, String data,
13254                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13255                                    throws RemoteException {
13256                            }
13257                        }, 0, null, null,
13258                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13259                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13260            } catch (Throwable t) {
13261                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13262            } finally {
13263                Binder.restoreCallingIdentity(ident);
13264            }
13265            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13266            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13267        }
13268    }
13269
13270    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13271        synchronized (this) {
13272            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13273        }
13274    }
13275
13276    void skipCurrentReceiverLocked(ProcessRecord app) {
13277        for (BroadcastQueue queue : mBroadcastQueues) {
13278            queue.skipCurrentReceiverLocked(app);
13279        }
13280    }
13281
13282    /**
13283     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13284     * The application process will exit immediately after this call returns.
13285     * @param app object of the crashing app, null for the system server
13286     * @param crashInfo describing the exception
13287     */
13288    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13289        ProcessRecord r = findAppProcess(app, "Crash");
13290        final String processName = app == null ? "system_server"
13291                : (r == null ? "unknown" : r.processName);
13292
13293        handleApplicationCrashInner("crash", r, processName, crashInfo);
13294    }
13295
13296    /* Native crash reporting uses this inner version because it needs to be somewhat
13297     * decoupled from the AM-managed cleanup lifecycle
13298     */
13299    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13300            ApplicationErrorReport.CrashInfo crashInfo) {
13301        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13302                UserHandle.getUserId(Binder.getCallingUid()), processName,
13303                r == null ? -1 : r.info.flags,
13304                crashInfo.exceptionClassName,
13305                crashInfo.exceptionMessage,
13306                crashInfo.throwFileName,
13307                crashInfo.throwLineNumber);
13308
13309        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13310
13311        mAppErrors.crashApplication(r, crashInfo);
13312    }
13313
13314    public void handleApplicationStrictModeViolation(
13315            IBinder app,
13316            int violationMask,
13317            StrictMode.ViolationInfo info) {
13318        ProcessRecord r = findAppProcess(app, "StrictMode");
13319        if (r == null) {
13320            return;
13321        }
13322
13323        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13324            Integer stackFingerprint = info.hashCode();
13325            boolean logIt = true;
13326            synchronized (mAlreadyLoggedViolatedStacks) {
13327                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13328                    logIt = false;
13329                    // TODO: sub-sample into EventLog for these, with
13330                    // the info.durationMillis?  Then we'd get
13331                    // the relative pain numbers, without logging all
13332                    // the stack traces repeatedly.  We'd want to do
13333                    // likewise in the client code, which also does
13334                    // dup suppression, before the Binder call.
13335                } else {
13336                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13337                        mAlreadyLoggedViolatedStacks.clear();
13338                    }
13339                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13340                }
13341            }
13342            if (logIt) {
13343                logStrictModeViolationToDropBox(r, info);
13344            }
13345        }
13346
13347        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13348            AppErrorResult result = new AppErrorResult();
13349            synchronized (this) {
13350                final long origId = Binder.clearCallingIdentity();
13351
13352                Message msg = Message.obtain();
13353                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13354                HashMap<String, Object> data = new HashMap<String, Object>();
13355                data.put("result", result);
13356                data.put("app", r);
13357                data.put("violationMask", violationMask);
13358                data.put("info", info);
13359                msg.obj = data;
13360                mUiHandler.sendMessage(msg);
13361
13362                Binder.restoreCallingIdentity(origId);
13363            }
13364            int res = result.get();
13365            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13366        }
13367    }
13368
13369    // Depending on the policy in effect, there could be a bunch of
13370    // these in quick succession so we try to batch these together to
13371    // minimize disk writes, number of dropbox entries, and maximize
13372    // compression, by having more fewer, larger records.
13373    private void logStrictModeViolationToDropBox(
13374            ProcessRecord process,
13375            StrictMode.ViolationInfo info) {
13376        if (info == null) {
13377            return;
13378        }
13379        final boolean isSystemApp = process == null ||
13380                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13381                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13382        final String processName = process == null ? "unknown" : process.processName;
13383        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13384        final DropBoxManager dbox = (DropBoxManager)
13385                mContext.getSystemService(Context.DROPBOX_SERVICE);
13386
13387        // Exit early if the dropbox isn't configured to accept this report type.
13388        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13389
13390        boolean bufferWasEmpty;
13391        boolean needsFlush;
13392        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13393        synchronized (sb) {
13394            bufferWasEmpty = sb.length() == 0;
13395            appendDropBoxProcessHeaders(process, processName, sb);
13396            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13397            sb.append("System-App: ").append(isSystemApp).append("\n");
13398            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13399            if (info.violationNumThisLoop != 0) {
13400                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13401            }
13402            if (info.numAnimationsRunning != 0) {
13403                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13404            }
13405            if (info.broadcastIntentAction != null) {
13406                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13407            }
13408            if (info.durationMillis != -1) {
13409                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13410            }
13411            if (info.numInstances != -1) {
13412                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13413            }
13414            if (info.tags != null) {
13415                for (String tag : info.tags) {
13416                    sb.append("Span-Tag: ").append(tag).append("\n");
13417                }
13418            }
13419            sb.append("\n");
13420            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13421                sb.append(info.crashInfo.stackTrace);
13422                sb.append("\n");
13423            }
13424            if (info.message != null) {
13425                sb.append(info.message);
13426                sb.append("\n");
13427            }
13428
13429            // Only buffer up to ~64k.  Various logging bits truncate
13430            // things at 128k.
13431            needsFlush = (sb.length() > 64 * 1024);
13432        }
13433
13434        // Flush immediately if the buffer's grown too large, or this
13435        // is a non-system app.  Non-system apps are isolated with a
13436        // different tag & policy and not batched.
13437        //
13438        // Batching is useful during internal testing with
13439        // StrictMode settings turned up high.  Without batching,
13440        // thousands of separate files could be created on boot.
13441        if (!isSystemApp || needsFlush) {
13442            new Thread("Error dump: " + dropboxTag) {
13443                @Override
13444                public void run() {
13445                    String report;
13446                    synchronized (sb) {
13447                        report = sb.toString();
13448                        sb.delete(0, sb.length());
13449                        sb.trimToSize();
13450                    }
13451                    if (report.length() != 0) {
13452                        dbox.addText(dropboxTag, report);
13453                    }
13454                }
13455            }.start();
13456            return;
13457        }
13458
13459        // System app batching:
13460        if (!bufferWasEmpty) {
13461            // An existing dropbox-writing thread is outstanding, so
13462            // we don't need to start it up.  The existing thread will
13463            // catch the buffer appends we just did.
13464            return;
13465        }
13466
13467        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13468        // (After this point, we shouldn't access AMS internal data structures.)
13469        new Thread("Error dump: " + dropboxTag) {
13470            @Override
13471            public void run() {
13472                // 5 second sleep to let stacks arrive and be batched together
13473                try {
13474                    Thread.sleep(5000);  // 5 seconds
13475                } catch (InterruptedException e) {}
13476
13477                String errorReport;
13478                synchronized (mStrictModeBuffer) {
13479                    errorReport = mStrictModeBuffer.toString();
13480                    if (errorReport.length() == 0) {
13481                        return;
13482                    }
13483                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13484                    mStrictModeBuffer.trimToSize();
13485                }
13486                dbox.addText(dropboxTag, errorReport);
13487            }
13488        }.start();
13489    }
13490
13491    /**
13492     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13493     * @param app object of the crashing app, null for the system server
13494     * @param tag reported by the caller
13495     * @param system whether this wtf is coming from the system
13496     * @param crashInfo describing the context of the error
13497     * @return true if the process should exit immediately (WTF is fatal)
13498     */
13499    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13500            final ApplicationErrorReport.CrashInfo crashInfo) {
13501        final int callingUid = Binder.getCallingUid();
13502        final int callingPid = Binder.getCallingPid();
13503
13504        if (system) {
13505            // If this is coming from the system, we could very well have low-level
13506            // system locks held, so we want to do this all asynchronously.  And we
13507            // never want this to become fatal, so there is that too.
13508            mHandler.post(new Runnable() {
13509                @Override public void run() {
13510                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13511                }
13512            });
13513            return false;
13514        }
13515
13516        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13517                crashInfo);
13518
13519        if (r != null && r.pid != Process.myPid() &&
13520                Settings.Global.getInt(mContext.getContentResolver(),
13521                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13522            mAppErrors.crashApplication(r, crashInfo);
13523            return true;
13524        } else {
13525            return false;
13526        }
13527    }
13528
13529    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13530            final ApplicationErrorReport.CrashInfo crashInfo) {
13531        final ProcessRecord r = findAppProcess(app, "WTF");
13532        final String processName = app == null ? "system_server"
13533                : (r == null ? "unknown" : r.processName);
13534
13535        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13536                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13537
13538        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13539
13540        return r;
13541    }
13542
13543    /**
13544     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13545     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13546     */
13547    private ProcessRecord findAppProcess(IBinder app, String reason) {
13548        if (app == null) {
13549            return null;
13550        }
13551
13552        synchronized (this) {
13553            final int NP = mProcessNames.getMap().size();
13554            for (int ip=0; ip<NP; ip++) {
13555                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13556                final int NA = apps.size();
13557                for (int ia=0; ia<NA; ia++) {
13558                    ProcessRecord p = apps.valueAt(ia);
13559                    if (p.thread != null && p.thread.asBinder() == app) {
13560                        return p;
13561                    }
13562                }
13563            }
13564
13565            Slog.w(TAG, "Can't find mystery application for " + reason
13566                    + " from pid=" + Binder.getCallingPid()
13567                    + " uid=" + Binder.getCallingUid() + ": " + app);
13568            return null;
13569        }
13570    }
13571
13572    /**
13573     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13574     * to append various headers to the dropbox log text.
13575     */
13576    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13577            StringBuilder sb) {
13578        // Watchdog thread ends up invoking this function (with
13579        // a null ProcessRecord) to add the stack file to dropbox.
13580        // Do not acquire a lock on this (am) in such cases, as it
13581        // could cause a potential deadlock, if and when watchdog
13582        // is invoked due to unavailability of lock on am and it
13583        // would prevent watchdog from killing system_server.
13584        if (process == null) {
13585            sb.append("Process: ").append(processName).append("\n");
13586            return;
13587        }
13588        // Note: ProcessRecord 'process' is guarded by the service
13589        // instance.  (notably process.pkgList, which could otherwise change
13590        // concurrently during execution of this method)
13591        synchronized (this) {
13592            sb.append("Process: ").append(processName).append("\n");
13593            int flags = process.info.flags;
13594            IPackageManager pm = AppGlobals.getPackageManager();
13595            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13596            for (int ip=0; ip<process.pkgList.size(); ip++) {
13597                String pkg = process.pkgList.keyAt(ip);
13598                sb.append("Package: ").append(pkg);
13599                try {
13600                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13601                    if (pi != null) {
13602                        sb.append(" v").append(pi.versionCode);
13603                        if (pi.versionName != null) {
13604                            sb.append(" (").append(pi.versionName).append(")");
13605                        }
13606                    }
13607                } catch (RemoteException e) {
13608                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13609                }
13610                sb.append("\n");
13611            }
13612        }
13613    }
13614
13615    private static String processClass(ProcessRecord process) {
13616        if (process == null || process.pid == MY_PID) {
13617            return "system_server";
13618        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13619            return "system_app";
13620        } else {
13621            return "data_app";
13622        }
13623    }
13624
13625    private volatile long mWtfClusterStart;
13626    private volatile int mWtfClusterCount;
13627
13628    /**
13629     * Write a description of an error (crash, WTF, ANR) to the drop box.
13630     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13631     * @param process which caused the error, null means the system server
13632     * @param activity which triggered the error, null if unknown
13633     * @param parent activity related to the error, null if unknown
13634     * @param subject line related to the error, null if absent
13635     * @param report in long form describing the error, null if absent
13636     * @param dataFile text file to include in the report, null if none
13637     * @param crashInfo giving an application stack trace, null if absent
13638     */
13639    public void addErrorToDropBox(String eventType,
13640            ProcessRecord process, String processName, ActivityRecord activity,
13641            ActivityRecord parent, String subject,
13642            final String report, final File dataFile,
13643            final ApplicationErrorReport.CrashInfo crashInfo) {
13644        // NOTE -- this must never acquire the ActivityManagerService lock,
13645        // otherwise the watchdog may be prevented from resetting the system.
13646
13647        final String dropboxTag = processClass(process) + "_" + eventType;
13648        final DropBoxManager dbox = (DropBoxManager)
13649                mContext.getSystemService(Context.DROPBOX_SERVICE);
13650
13651        // Exit early if the dropbox isn't configured to accept this report type.
13652        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13653
13654        // Rate-limit how often we're willing to do the heavy lifting below to
13655        // collect and record logs; currently 5 logs per 10 second period.
13656        final long now = SystemClock.elapsedRealtime();
13657        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13658            mWtfClusterStart = now;
13659            mWtfClusterCount = 1;
13660        } else {
13661            if (mWtfClusterCount++ >= 5) return;
13662        }
13663
13664        final StringBuilder sb = new StringBuilder(1024);
13665        appendDropBoxProcessHeaders(process, processName, sb);
13666        if (process != null) {
13667            sb.append("Foreground: ")
13668                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13669                    .append("\n");
13670        }
13671        if (activity != null) {
13672            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13673        }
13674        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13675            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13676        }
13677        if (parent != null && parent != activity) {
13678            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13679        }
13680        if (subject != null) {
13681            sb.append("Subject: ").append(subject).append("\n");
13682        }
13683        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13684        if (Debug.isDebuggerConnected()) {
13685            sb.append("Debugger: Connected\n");
13686        }
13687        sb.append("\n");
13688
13689        // Do the rest in a worker thread to avoid blocking the caller on I/O
13690        // (After this point, we shouldn't access AMS internal data structures.)
13691        Thread worker = new Thread("Error dump: " + dropboxTag) {
13692            @Override
13693            public void run() {
13694                if (report != null) {
13695                    sb.append(report);
13696                }
13697
13698                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13699                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13700                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13701                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13702
13703                if (dataFile != null && maxDataFileSize > 0) {
13704                    try {
13705                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13706                                    "\n\n[[TRUNCATED]]"));
13707                    } catch (IOException e) {
13708                        Slog.e(TAG, "Error reading " + dataFile, e);
13709                    }
13710                }
13711                if (crashInfo != null && crashInfo.stackTrace != null) {
13712                    sb.append(crashInfo.stackTrace);
13713                }
13714
13715                if (lines > 0) {
13716                    sb.append("\n");
13717
13718                    // Merge several logcat streams, and take the last N lines
13719                    InputStreamReader input = null;
13720                    try {
13721                        java.lang.Process logcat = new ProcessBuilder(
13722                                "/system/bin/timeout", "-k", "15s", "10s",
13723                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13724                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13725                                        .redirectErrorStream(true).start();
13726
13727                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13728                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13729                        input = new InputStreamReader(logcat.getInputStream());
13730
13731                        int num;
13732                        char[] buf = new char[8192];
13733                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13734                    } catch (IOException e) {
13735                        Slog.e(TAG, "Error running logcat", e);
13736                    } finally {
13737                        if (input != null) try { input.close(); } catch (IOException e) {}
13738                    }
13739                }
13740
13741                dbox.addText(dropboxTag, sb.toString());
13742            }
13743        };
13744
13745        if (process == null) {
13746            // If process is null, we are being called from some internal code
13747            // and may be about to die -- run this synchronously.
13748            worker.run();
13749        } else {
13750            worker.start();
13751        }
13752    }
13753
13754    @Override
13755    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13756        enforceNotIsolatedCaller("getProcessesInErrorState");
13757        // assume our apps are happy - lazy create the list
13758        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13759
13760        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13761                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13762        int userId = UserHandle.getUserId(Binder.getCallingUid());
13763
13764        synchronized (this) {
13765
13766            // iterate across all processes
13767            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13768                ProcessRecord app = mLruProcesses.get(i);
13769                if (!allUsers && app.userId != userId) {
13770                    continue;
13771                }
13772                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13773                    // This one's in trouble, so we'll generate a report for it
13774                    // crashes are higher priority (in case there's a crash *and* an anr)
13775                    ActivityManager.ProcessErrorStateInfo report = null;
13776                    if (app.crashing) {
13777                        report = app.crashingReport;
13778                    } else if (app.notResponding) {
13779                        report = app.notRespondingReport;
13780                    }
13781
13782                    if (report != null) {
13783                        if (errList == null) {
13784                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13785                        }
13786                        errList.add(report);
13787                    } else {
13788                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13789                                " crashing = " + app.crashing +
13790                                " notResponding = " + app.notResponding);
13791                    }
13792                }
13793            }
13794        }
13795
13796        return errList;
13797    }
13798
13799    static int procStateToImportance(int procState, int memAdj,
13800            ActivityManager.RunningAppProcessInfo currApp) {
13801        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13802        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13803            currApp.lru = memAdj;
13804        } else {
13805            currApp.lru = 0;
13806        }
13807        return imp;
13808    }
13809
13810    private void fillInProcMemInfo(ProcessRecord app,
13811            ActivityManager.RunningAppProcessInfo outInfo) {
13812        outInfo.pid = app.pid;
13813        outInfo.uid = app.info.uid;
13814        if (mHeavyWeightProcess == app) {
13815            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13816        }
13817        if (app.persistent) {
13818            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13819        }
13820        if (app.activities.size() > 0) {
13821            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13822        }
13823        outInfo.lastTrimLevel = app.trimMemoryLevel;
13824        int adj = app.curAdj;
13825        int procState = app.curProcState;
13826        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13827        outInfo.importanceReasonCode = app.adjTypeCode;
13828        outInfo.processState = app.curProcState;
13829    }
13830
13831    @Override
13832    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13833        enforceNotIsolatedCaller("getRunningAppProcesses");
13834
13835        final int callingUid = Binder.getCallingUid();
13836
13837        // Lazy instantiation of list
13838        List<ActivityManager.RunningAppProcessInfo> runList = null;
13839        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13840                callingUid) == PackageManager.PERMISSION_GRANTED;
13841        final int userId = UserHandle.getUserId(callingUid);
13842        final boolean allUids = isGetTasksAllowed(
13843                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13844
13845        synchronized (this) {
13846            // Iterate across all processes
13847            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13848                ProcessRecord app = mLruProcesses.get(i);
13849                if ((!allUsers && app.userId != userId)
13850                        || (!allUids && app.uid != callingUid)) {
13851                    continue;
13852                }
13853                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13854                    // Generate process state info for running application
13855                    ActivityManager.RunningAppProcessInfo currApp =
13856                        new ActivityManager.RunningAppProcessInfo(app.processName,
13857                                app.pid, app.getPackageList());
13858                    fillInProcMemInfo(app, currApp);
13859                    if (app.adjSource instanceof ProcessRecord) {
13860                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13861                        currApp.importanceReasonImportance =
13862                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13863                                        app.adjSourceProcState);
13864                    } else if (app.adjSource instanceof ActivityRecord) {
13865                        ActivityRecord r = (ActivityRecord)app.adjSource;
13866                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13867                    }
13868                    if (app.adjTarget instanceof ComponentName) {
13869                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13870                    }
13871                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13872                    //        + " lru=" + currApp.lru);
13873                    if (runList == null) {
13874                        runList = new ArrayList<>();
13875                    }
13876                    runList.add(currApp);
13877                }
13878            }
13879        }
13880        return runList;
13881    }
13882
13883    @Override
13884    public List<ApplicationInfo> getRunningExternalApplications() {
13885        enforceNotIsolatedCaller("getRunningExternalApplications");
13886        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13887        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13888        if (runningApps != null && runningApps.size() > 0) {
13889            Set<String> extList = new HashSet<String>();
13890            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13891                if (app.pkgList != null) {
13892                    for (String pkg : app.pkgList) {
13893                        extList.add(pkg);
13894                    }
13895                }
13896            }
13897            IPackageManager pm = AppGlobals.getPackageManager();
13898            for (String pkg : extList) {
13899                try {
13900                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13901                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13902                        retList.add(info);
13903                    }
13904                } catch (RemoteException e) {
13905                }
13906            }
13907        }
13908        return retList;
13909    }
13910
13911    @Override
13912    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13913        enforceNotIsolatedCaller("getMyMemoryState");
13914        synchronized (this) {
13915            ProcessRecord proc;
13916            synchronized (mPidsSelfLocked) {
13917                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13918            }
13919            fillInProcMemInfo(proc, outInfo);
13920        }
13921    }
13922
13923    @Override
13924    public int getMemoryTrimLevel() {
13925        enforceNotIsolatedCaller("getMyMemoryState");
13926        synchronized (this) {
13927            return mLastMemoryLevel;
13928        }
13929    }
13930
13931    @Override
13932    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13933            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13934        (new ActivityManagerShellCommand(this, false)).exec(
13935                this, in, out, err, args, resultReceiver);
13936    }
13937
13938    @Override
13939    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13940        if (checkCallingPermission(android.Manifest.permission.DUMP)
13941                != PackageManager.PERMISSION_GRANTED) {
13942            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13943                    + Binder.getCallingPid()
13944                    + ", uid=" + Binder.getCallingUid()
13945                    + " without permission "
13946                    + android.Manifest.permission.DUMP);
13947            return;
13948        }
13949
13950        boolean dumpAll = false;
13951        boolean dumpClient = false;
13952        boolean dumpCheckin = false;
13953        boolean dumpCheckinFormat = false;
13954        String dumpPackage = null;
13955
13956        int opti = 0;
13957        while (opti < args.length) {
13958            String opt = args[opti];
13959            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13960                break;
13961            }
13962            opti++;
13963            if ("-a".equals(opt)) {
13964                dumpAll = true;
13965            } else if ("-c".equals(opt)) {
13966                dumpClient = true;
13967            } else if ("-p".equals(opt)) {
13968                if (opti < args.length) {
13969                    dumpPackage = args[opti];
13970                    opti++;
13971                } else {
13972                    pw.println("Error: -p option requires package argument");
13973                    return;
13974                }
13975                dumpClient = true;
13976            } else if ("--checkin".equals(opt)) {
13977                dumpCheckin = dumpCheckinFormat = true;
13978            } else if ("-C".equals(opt)) {
13979                dumpCheckinFormat = true;
13980            } else if ("-h".equals(opt)) {
13981                ActivityManagerShellCommand.dumpHelp(pw, true);
13982                return;
13983            } else {
13984                pw.println("Unknown argument: " + opt + "; use -h for help");
13985            }
13986        }
13987
13988        long origId = Binder.clearCallingIdentity();
13989        boolean more = false;
13990        // Is the caller requesting to dump a particular piece of data?
13991        if (opti < args.length) {
13992            String cmd = args[opti];
13993            opti++;
13994            if ("activities".equals(cmd) || "a".equals(cmd)) {
13995                synchronized (this) {
13996                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13997                }
13998            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13999                synchronized (this) {
14000                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14001                }
14002            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14003                String[] newArgs;
14004                String name;
14005                if (opti >= args.length) {
14006                    name = null;
14007                    newArgs = EMPTY_STRING_ARRAY;
14008                } else {
14009                    dumpPackage = args[opti];
14010                    opti++;
14011                    newArgs = new String[args.length - opti];
14012                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14013                            args.length - opti);
14014                }
14015                synchronized (this) {
14016                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14017                }
14018            } else if ("broadcast-stats".equals(cmd)) {
14019                String[] newArgs;
14020                String name;
14021                if (opti >= args.length) {
14022                    name = null;
14023                    newArgs = EMPTY_STRING_ARRAY;
14024                } else {
14025                    dumpPackage = args[opti];
14026                    opti++;
14027                    newArgs = new String[args.length - opti];
14028                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14029                            args.length - opti);
14030                }
14031                synchronized (this) {
14032                    if (dumpCheckinFormat) {
14033                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14034                                dumpPackage);
14035                    } else {
14036                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14037                    }
14038                }
14039            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14040                String[] newArgs;
14041                String name;
14042                if (opti >= args.length) {
14043                    name = null;
14044                    newArgs = EMPTY_STRING_ARRAY;
14045                } else {
14046                    dumpPackage = args[opti];
14047                    opti++;
14048                    newArgs = new String[args.length - opti];
14049                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14050                            args.length - opti);
14051                }
14052                synchronized (this) {
14053                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14054                }
14055            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14056                String[] newArgs;
14057                String name;
14058                if (opti >= args.length) {
14059                    name = null;
14060                    newArgs = EMPTY_STRING_ARRAY;
14061                } else {
14062                    dumpPackage = args[opti];
14063                    opti++;
14064                    newArgs = new String[args.length - opti];
14065                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14066                            args.length - opti);
14067                }
14068                synchronized (this) {
14069                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14070                }
14071            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14072                synchronized (this) {
14073                    dumpOomLocked(fd, pw, args, opti, true);
14074                }
14075            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14076                synchronized (this) {
14077                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14078                }
14079            } else if ("provider".equals(cmd)) {
14080                String[] newArgs;
14081                String name;
14082                if (opti >= args.length) {
14083                    name = null;
14084                    newArgs = EMPTY_STRING_ARRAY;
14085                } else {
14086                    name = args[opti];
14087                    opti++;
14088                    newArgs = new String[args.length - opti];
14089                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14090                }
14091                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14092                    pw.println("No providers match: " + name);
14093                    pw.println("Use -h for help.");
14094                }
14095            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14096                synchronized (this) {
14097                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14098                }
14099            } else if ("service".equals(cmd)) {
14100                String[] newArgs;
14101                String name;
14102                if (opti >= args.length) {
14103                    name = null;
14104                    newArgs = EMPTY_STRING_ARRAY;
14105                } else {
14106                    name = args[opti];
14107                    opti++;
14108                    newArgs = new String[args.length - opti];
14109                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14110                            args.length - opti);
14111                }
14112                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14113                    pw.println("No services match: " + name);
14114                    pw.println("Use -h for help.");
14115                }
14116            } else if ("package".equals(cmd)) {
14117                String[] newArgs;
14118                if (opti >= args.length) {
14119                    pw.println("package: no package name specified");
14120                    pw.println("Use -h for help.");
14121                } else {
14122                    dumpPackage = args[opti];
14123                    opti++;
14124                    newArgs = new String[args.length - opti];
14125                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14126                            args.length - opti);
14127                    args = newArgs;
14128                    opti = 0;
14129                    more = true;
14130                }
14131            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14132                synchronized (this) {
14133                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14134                }
14135            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14136                if (dumpClient) {
14137                    ActiveServices.ServiceDumper dumper;
14138                    synchronized (this) {
14139                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14140                                dumpPackage);
14141                    }
14142                    dumper.dumpWithClient();
14143                } else {
14144                    synchronized (this) {
14145                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14146                                dumpPackage).dumpLocked();
14147                    }
14148                }
14149            } else if ("locks".equals(cmd)) {
14150                LockGuard.dump(fd, pw, args);
14151            } else {
14152                // Dumping a single activity?
14153                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14154                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14155                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14156                    if (res < 0) {
14157                        pw.println("Bad activity command, or no activities match: " + cmd);
14158                        pw.println("Use -h for help.");
14159                    }
14160                }
14161            }
14162            if (!more) {
14163                Binder.restoreCallingIdentity(origId);
14164                return;
14165            }
14166        }
14167
14168        // No piece of data specified, dump everything.
14169        if (dumpCheckinFormat) {
14170            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14171        } else if (dumpClient) {
14172            ActiveServices.ServiceDumper sdumper;
14173            synchronized (this) {
14174                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14175                pw.println();
14176                if (dumpAll) {
14177                    pw.println("-------------------------------------------------------------------------------");
14178                }
14179                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14180                pw.println();
14181                if (dumpAll) {
14182                    pw.println("-------------------------------------------------------------------------------");
14183                }
14184                if (dumpAll || dumpPackage != null) {
14185                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14186                    pw.println();
14187                    if (dumpAll) {
14188                        pw.println("-------------------------------------------------------------------------------");
14189                    }
14190                }
14191                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14192                pw.println();
14193                if (dumpAll) {
14194                    pw.println("-------------------------------------------------------------------------------");
14195                }
14196                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14197                pw.println();
14198                if (dumpAll) {
14199                    pw.println("-------------------------------------------------------------------------------");
14200                }
14201                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14202                        dumpPackage);
14203            }
14204            sdumper.dumpWithClient();
14205            pw.println();
14206            synchronized (this) {
14207                if (dumpAll) {
14208                    pw.println("-------------------------------------------------------------------------------");
14209                }
14210                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14211                pw.println();
14212                if (dumpAll) {
14213                    pw.println("-------------------------------------------------------------------------------");
14214                }
14215                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14216                if (mAssociations.size() > 0) {
14217                    pw.println();
14218                    if (dumpAll) {
14219                        pw.println("-------------------------------------------------------------------------------");
14220                    }
14221                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14222                }
14223                pw.println();
14224                if (dumpAll) {
14225                    pw.println("-------------------------------------------------------------------------------");
14226                }
14227                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14228            }
14229
14230        } else {
14231            synchronized (this) {
14232                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14233                pw.println();
14234                if (dumpAll) {
14235                    pw.println("-------------------------------------------------------------------------------");
14236                }
14237                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14238                pw.println();
14239                if (dumpAll) {
14240                    pw.println("-------------------------------------------------------------------------------");
14241                }
14242                if (dumpAll || dumpPackage != null) {
14243                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14244                    pw.println();
14245                    if (dumpAll) {
14246                        pw.println("-------------------------------------------------------------------------------");
14247                    }
14248                }
14249                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14250                pw.println();
14251                if (dumpAll) {
14252                    pw.println("-------------------------------------------------------------------------------");
14253                }
14254                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14255                pw.println();
14256                if (dumpAll) {
14257                    pw.println("-------------------------------------------------------------------------------");
14258                }
14259                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14260                        .dumpLocked();
14261                pw.println();
14262                if (dumpAll) {
14263                    pw.println("-------------------------------------------------------------------------------");
14264                }
14265                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14266                pw.println();
14267                if (dumpAll) {
14268                    pw.println("-------------------------------------------------------------------------------");
14269                }
14270                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14271                if (mAssociations.size() > 0) {
14272                    pw.println();
14273                    if (dumpAll) {
14274                        pw.println("-------------------------------------------------------------------------------");
14275                    }
14276                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14277                }
14278                pw.println();
14279                if (dumpAll) {
14280                    pw.println("-------------------------------------------------------------------------------");
14281                }
14282                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14283            }
14284        }
14285        Binder.restoreCallingIdentity(origId);
14286    }
14287
14288    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14289            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14290        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14291
14292        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14293                dumpPackage);
14294        boolean needSep = printedAnything;
14295
14296        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14297                dumpPackage, needSep, "  mFocusedActivity: ");
14298        if (printed) {
14299            printedAnything = true;
14300            needSep = false;
14301        }
14302
14303        if (dumpPackage == null) {
14304            if (needSep) {
14305                pw.println();
14306            }
14307            needSep = true;
14308            printedAnything = true;
14309            mStackSupervisor.dump(pw, "  ");
14310        }
14311
14312        if (!printedAnything) {
14313            pw.println("  (nothing)");
14314        }
14315    }
14316
14317    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14318            int opti, boolean dumpAll, String dumpPackage) {
14319        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14320
14321        boolean printedAnything = false;
14322
14323        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14324            boolean printedHeader = false;
14325
14326            final int N = mRecentTasks.size();
14327            for (int i=0; i<N; i++) {
14328                TaskRecord tr = mRecentTasks.get(i);
14329                if (dumpPackage != null) {
14330                    if (tr.realActivity == null ||
14331                            !dumpPackage.equals(tr.realActivity)) {
14332                        continue;
14333                    }
14334                }
14335                if (!printedHeader) {
14336                    pw.println("  Recent tasks:");
14337                    printedHeader = true;
14338                    printedAnything = true;
14339                }
14340                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14341                        pw.println(tr);
14342                if (dumpAll) {
14343                    mRecentTasks.get(i).dump(pw, "    ");
14344                }
14345            }
14346        }
14347
14348        if (!printedAnything) {
14349            pw.println("  (nothing)");
14350        }
14351    }
14352
14353    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14354            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14355        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14356
14357        int dumpUid = 0;
14358        if (dumpPackage != null) {
14359            IPackageManager pm = AppGlobals.getPackageManager();
14360            try {
14361                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14362            } catch (RemoteException e) {
14363            }
14364        }
14365
14366        boolean printedAnything = false;
14367
14368        final long now = SystemClock.uptimeMillis();
14369
14370        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14371            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14372                    = mAssociations.valueAt(i1);
14373            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14374                SparseArray<ArrayMap<String, Association>> sourceUids
14375                        = targetComponents.valueAt(i2);
14376                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14377                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14378                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14379                        Association ass = sourceProcesses.valueAt(i4);
14380                        if (dumpPackage != null) {
14381                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14382                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14383                                continue;
14384                            }
14385                        }
14386                        printedAnything = true;
14387                        pw.print("  ");
14388                        pw.print(ass.mTargetProcess);
14389                        pw.print("/");
14390                        UserHandle.formatUid(pw, ass.mTargetUid);
14391                        pw.print(" <- ");
14392                        pw.print(ass.mSourceProcess);
14393                        pw.print("/");
14394                        UserHandle.formatUid(pw, ass.mSourceUid);
14395                        pw.println();
14396                        pw.print("    via ");
14397                        pw.print(ass.mTargetComponent.flattenToShortString());
14398                        pw.println();
14399                        pw.print("    ");
14400                        long dur = ass.mTime;
14401                        if (ass.mNesting > 0) {
14402                            dur += now - ass.mStartTime;
14403                        }
14404                        TimeUtils.formatDuration(dur, pw);
14405                        pw.print(" (");
14406                        pw.print(ass.mCount);
14407                        pw.print(" times)");
14408                        pw.print("  ");
14409                        for (int i=0; i<ass.mStateTimes.length; i++) {
14410                            long amt = ass.mStateTimes[i];
14411                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14412                                amt += now - ass.mLastStateUptime;
14413                            }
14414                            if (amt != 0) {
14415                                pw.print(" ");
14416                                pw.print(ProcessList.makeProcStateString(
14417                                            i + ActivityManager.MIN_PROCESS_STATE));
14418                                pw.print("=");
14419                                TimeUtils.formatDuration(amt, pw);
14420                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14421                                    pw.print("*");
14422                                }
14423                            }
14424                        }
14425                        pw.println();
14426                        if (ass.mNesting > 0) {
14427                            pw.print("    Currently active: ");
14428                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14429                            pw.println();
14430                        }
14431                    }
14432                }
14433            }
14434
14435        }
14436
14437        if (!printedAnything) {
14438            pw.println("  (nothing)");
14439        }
14440    }
14441
14442    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14443            String header, boolean needSep) {
14444        boolean printed = false;
14445        int whichAppId = -1;
14446        if (dumpPackage != null) {
14447            try {
14448                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14449                        dumpPackage, 0);
14450                whichAppId = UserHandle.getAppId(info.uid);
14451            } catch (NameNotFoundException e) {
14452                e.printStackTrace();
14453            }
14454        }
14455        for (int i=0; i<uids.size(); i++) {
14456            UidRecord uidRec = uids.valueAt(i);
14457            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14458                continue;
14459            }
14460            if (!printed) {
14461                printed = true;
14462                if (needSep) {
14463                    pw.println();
14464                }
14465                pw.print("  ");
14466                pw.println(header);
14467                needSep = true;
14468            }
14469            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14470            pw.print(": "); pw.println(uidRec);
14471        }
14472        return printed;
14473    }
14474
14475    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14476            int opti, boolean dumpAll, String dumpPackage) {
14477        boolean needSep = false;
14478        boolean printedAnything = false;
14479        int numPers = 0;
14480
14481        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14482
14483        if (dumpAll) {
14484            final int NP = mProcessNames.getMap().size();
14485            for (int ip=0; ip<NP; ip++) {
14486                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14487                final int NA = procs.size();
14488                for (int ia=0; ia<NA; ia++) {
14489                    ProcessRecord r = procs.valueAt(ia);
14490                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14491                        continue;
14492                    }
14493                    if (!needSep) {
14494                        pw.println("  All known processes:");
14495                        needSep = true;
14496                        printedAnything = true;
14497                    }
14498                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14499                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14500                        pw.print(" "); pw.println(r);
14501                    r.dump(pw, "    ");
14502                    if (r.persistent) {
14503                        numPers++;
14504                    }
14505                }
14506            }
14507        }
14508
14509        if (mIsolatedProcesses.size() > 0) {
14510            boolean printed = false;
14511            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14512                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14513                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14514                    continue;
14515                }
14516                if (!printed) {
14517                    if (needSep) {
14518                        pw.println();
14519                    }
14520                    pw.println("  Isolated process list (sorted by uid):");
14521                    printedAnything = true;
14522                    printed = true;
14523                    needSep = true;
14524                }
14525                pw.println(String.format("%sIsolated #%2d: %s",
14526                        "    ", i, r.toString()));
14527            }
14528        }
14529
14530        if (mActiveUids.size() > 0) {
14531            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14532                printedAnything = needSep = true;
14533            }
14534        }
14535        if (mValidateUids.size() > 0) {
14536            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14537                printedAnything = needSep = true;
14538            }
14539        }
14540
14541        if (mLruProcesses.size() > 0) {
14542            if (needSep) {
14543                pw.println();
14544            }
14545            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14546                    pw.print(" total, non-act at ");
14547                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14548                    pw.print(", non-svc at ");
14549                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14550                    pw.println("):");
14551            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14552            needSep = true;
14553            printedAnything = true;
14554        }
14555
14556        if (dumpAll || dumpPackage != null) {
14557            synchronized (mPidsSelfLocked) {
14558                boolean printed = false;
14559                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14560                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14561                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14562                        continue;
14563                    }
14564                    if (!printed) {
14565                        if (needSep) pw.println();
14566                        needSep = true;
14567                        pw.println("  PID mappings:");
14568                        printed = true;
14569                        printedAnything = true;
14570                    }
14571                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14572                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14573                }
14574            }
14575        }
14576
14577        if (mForegroundProcesses.size() > 0) {
14578            synchronized (mPidsSelfLocked) {
14579                boolean printed = false;
14580                for (int i=0; i<mForegroundProcesses.size(); i++) {
14581                    ProcessRecord r = mPidsSelfLocked.get(
14582                            mForegroundProcesses.valueAt(i).pid);
14583                    if (dumpPackage != null && (r == null
14584                            || !r.pkgList.containsKey(dumpPackage))) {
14585                        continue;
14586                    }
14587                    if (!printed) {
14588                        if (needSep) pw.println();
14589                        needSep = true;
14590                        pw.println("  Foreground Processes:");
14591                        printed = true;
14592                        printedAnything = true;
14593                    }
14594                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14595                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14596                }
14597            }
14598        }
14599
14600        if (mPersistentStartingProcesses.size() > 0) {
14601            if (needSep) pw.println();
14602            needSep = true;
14603            printedAnything = true;
14604            pw.println("  Persisent processes that are starting:");
14605            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14606                    "Starting Norm", "Restarting PERS", dumpPackage);
14607        }
14608
14609        if (mRemovedProcesses.size() > 0) {
14610            if (needSep) pw.println();
14611            needSep = true;
14612            printedAnything = true;
14613            pw.println("  Processes that are being removed:");
14614            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14615                    "Removed Norm", "Removed PERS", dumpPackage);
14616        }
14617
14618        if (mProcessesOnHold.size() > 0) {
14619            if (needSep) pw.println();
14620            needSep = true;
14621            printedAnything = true;
14622            pw.println("  Processes that are on old until the system is ready:");
14623            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14624                    "OnHold Norm", "OnHold PERS", dumpPackage);
14625        }
14626
14627        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14628
14629        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14630        if (needSep) {
14631            printedAnything = true;
14632        }
14633
14634        if (dumpPackage == null) {
14635            pw.println();
14636            needSep = false;
14637            mUserController.dump(pw, dumpAll);
14638        }
14639        if (mHomeProcess != null && (dumpPackage == null
14640                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14641            if (needSep) {
14642                pw.println();
14643                needSep = false;
14644            }
14645            pw.println("  mHomeProcess: " + mHomeProcess);
14646        }
14647        if (mPreviousProcess != null && (dumpPackage == null
14648                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14649            if (needSep) {
14650                pw.println();
14651                needSep = false;
14652            }
14653            pw.println("  mPreviousProcess: " + mPreviousProcess);
14654        }
14655        if (dumpAll) {
14656            StringBuilder sb = new StringBuilder(128);
14657            sb.append("  mPreviousProcessVisibleTime: ");
14658            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14659            pw.println(sb);
14660        }
14661        if (mHeavyWeightProcess != null && (dumpPackage == null
14662                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14663            if (needSep) {
14664                pw.println();
14665                needSep = false;
14666            }
14667            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14668        }
14669        if (dumpPackage == null) {
14670            pw.println("  mConfiguration: " + mConfiguration);
14671        }
14672        if (dumpAll) {
14673            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14674            if (mCompatModePackages.getPackages().size() > 0) {
14675                boolean printed = false;
14676                for (Map.Entry<String, Integer> entry
14677                        : mCompatModePackages.getPackages().entrySet()) {
14678                    String pkg = entry.getKey();
14679                    int mode = entry.getValue();
14680                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14681                        continue;
14682                    }
14683                    if (!printed) {
14684                        pw.println("  mScreenCompatPackages:");
14685                        printed = true;
14686                    }
14687                    pw.print("    "); pw.print(pkg); pw.print(": ");
14688                            pw.print(mode); pw.println();
14689                }
14690            }
14691        }
14692        if (dumpPackage == null) {
14693            pw.println("  mWakefulness="
14694                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14695            pw.println("  mSleepTokens=" + mSleepTokens);
14696            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14697                    + lockScreenShownToString());
14698            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14699            if (mRunningVoice != null) {
14700                pw.println("  mRunningVoice=" + mRunningVoice);
14701                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14702            }
14703        }
14704        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14705                || mOrigWaitForDebugger) {
14706            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14707                    || dumpPackage.equals(mOrigDebugApp)) {
14708                if (needSep) {
14709                    pw.println();
14710                    needSep = false;
14711                }
14712                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14713                        + " mDebugTransient=" + mDebugTransient
14714                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14715            }
14716        }
14717        if (mCurAppTimeTracker != null) {
14718            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14719        }
14720        if (mMemWatchProcesses.getMap().size() > 0) {
14721            pw.println("  Mem watch processes:");
14722            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14723                    = mMemWatchProcesses.getMap();
14724            for (int i=0; i<procs.size(); i++) {
14725                final String proc = procs.keyAt(i);
14726                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14727                for (int j=0; j<uids.size(); j++) {
14728                    if (needSep) {
14729                        pw.println();
14730                        needSep = false;
14731                    }
14732                    StringBuilder sb = new StringBuilder();
14733                    sb.append("    ").append(proc).append('/');
14734                    UserHandle.formatUid(sb, uids.keyAt(j));
14735                    Pair<Long, String> val = uids.valueAt(j);
14736                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14737                    if (val.second != null) {
14738                        sb.append(", report to ").append(val.second);
14739                    }
14740                    pw.println(sb.toString());
14741                }
14742            }
14743            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14744            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14745            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14746                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14747        }
14748        if (mTrackAllocationApp != null) {
14749            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14750                if (needSep) {
14751                    pw.println();
14752                    needSep = false;
14753                }
14754                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14755            }
14756        }
14757        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14758                || mProfileFd != null) {
14759            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14760                if (needSep) {
14761                    pw.println();
14762                    needSep = false;
14763                }
14764                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14765                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14766                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14767                        + mAutoStopProfiler);
14768                pw.println("  mProfileType=" + mProfileType);
14769            }
14770        }
14771        if (mNativeDebuggingApp != null) {
14772            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14773                if (needSep) {
14774                    pw.println();
14775                    needSep = false;
14776                }
14777                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14778            }
14779        }
14780        if (dumpPackage == null) {
14781            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14782                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14783                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14784            }
14785            if (mController != null) {
14786                pw.println("  mController=" + mController
14787                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14788            }
14789            if (dumpAll) {
14790                pw.println("  Total persistent processes: " + numPers);
14791                pw.println("  mProcessesReady=" + mProcessesReady
14792                        + " mSystemReady=" + mSystemReady
14793                        + " mBooted=" + mBooted
14794                        + " mFactoryTest=" + mFactoryTest);
14795                pw.println("  mBooting=" + mBooting
14796                        + " mCallFinishBooting=" + mCallFinishBooting
14797                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14798                pw.print("  mLastPowerCheckRealtime=");
14799                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14800                        pw.println("");
14801                pw.print("  mLastPowerCheckUptime=");
14802                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14803                        pw.println("");
14804                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14805                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14806                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14807                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14808                        + " (" + mLruProcesses.size() + " total)"
14809                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14810                        + " mNumServiceProcs=" + mNumServiceProcs
14811                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14812                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14813                        + " mLastMemoryLevel=" + mLastMemoryLevel
14814                        + " mLastNumProcesses=" + mLastNumProcesses);
14815                long now = SystemClock.uptimeMillis();
14816                pw.print("  mLastIdleTime=");
14817                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14818                        pw.print(" mLowRamSinceLastIdle=");
14819                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14820                        pw.println();
14821            }
14822        }
14823
14824        if (!printedAnything) {
14825            pw.println("  (nothing)");
14826        }
14827    }
14828
14829    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14830            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14831        if (mProcessesToGc.size() > 0) {
14832            boolean printed = false;
14833            long now = SystemClock.uptimeMillis();
14834            for (int i=0; i<mProcessesToGc.size(); i++) {
14835                ProcessRecord proc = mProcessesToGc.get(i);
14836                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14837                    continue;
14838                }
14839                if (!printed) {
14840                    if (needSep) pw.println();
14841                    needSep = true;
14842                    pw.println("  Processes that are waiting to GC:");
14843                    printed = true;
14844                }
14845                pw.print("    Process "); pw.println(proc);
14846                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14847                        pw.print(", last gced=");
14848                        pw.print(now-proc.lastRequestedGc);
14849                        pw.print(" ms ago, last lowMem=");
14850                        pw.print(now-proc.lastLowMemory);
14851                        pw.println(" ms ago");
14852
14853            }
14854        }
14855        return needSep;
14856    }
14857
14858    void printOomLevel(PrintWriter pw, String name, int adj) {
14859        pw.print("    ");
14860        if (adj >= 0) {
14861            pw.print(' ');
14862            if (adj < 10) pw.print(' ');
14863        } else {
14864            if (adj > -10) pw.print(' ');
14865        }
14866        pw.print(adj);
14867        pw.print(": ");
14868        pw.print(name);
14869        pw.print(" (");
14870        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14871        pw.println(")");
14872    }
14873
14874    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14875            int opti, boolean dumpAll) {
14876        boolean needSep = false;
14877
14878        if (mLruProcesses.size() > 0) {
14879            if (needSep) pw.println();
14880            needSep = true;
14881            pw.println("  OOM levels:");
14882            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14883            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14884            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14885            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14886            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14887            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14888            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14889            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14890            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14891            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14892            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14893            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14894            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14895            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14896
14897            if (needSep) pw.println();
14898            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14899                    pw.print(" total, non-act at ");
14900                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14901                    pw.print(", non-svc at ");
14902                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14903                    pw.println("):");
14904            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14905            needSep = true;
14906        }
14907
14908        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14909
14910        pw.println();
14911        pw.println("  mHomeProcess: " + mHomeProcess);
14912        pw.println("  mPreviousProcess: " + mPreviousProcess);
14913        if (mHeavyWeightProcess != null) {
14914            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14915        }
14916
14917        return true;
14918    }
14919
14920    /**
14921     * There are three ways to call this:
14922     *  - no provider specified: dump all the providers
14923     *  - a flattened component name that matched an existing provider was specified as the
14924     *    first arg: dump that one provider
14925     *  - the first arg isn't the flattened component name of an existing provider:
14926     *    dump all providers whose component contains the first arg as a substring
14927     */
14928    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14929            int opti, boolean dumpAll) {
14930        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14931    }
14932
14933    static class ItemMatcher {
14934        ArrayList<ComponentName> components;
14935        ArrayList<String> strings;
14936        ArrayList<Integer> objects;
14937        boolean all;
14938
14939        ItemMatcher() {
14940            all = true;
14941        }
14942
14943        void build(String name) {
14944            ComponentName componentName = ComponentName.unflattenFromString(name);
14945            if (componentName != null) {
14946                if (components == null) {
14947                    components = new ArrayList<ComponentName>();
14948                }
14949                components.add(componentName);
14950                all = false;
14951            } else {
14952                int objectId = 0;
14953                // Not a '/' separated full component name; maybe an object ID?
14954                try {
14955                    objectId = Integer.parseInt(name, 16);
14956                    if (objects == null) {
14957                        objects = new ArrayList<Integer>();
14958                    }
14959                    objects.add(objectId);
14960                    all = false;
14961                } catch (RuntimeException e) {
14962                    // Not an integer; just do string match.
14963                    if (strings == null) {
14964                        strings = new ArrayList<String>();
14965                    }
14966                    strings.add(name);
14967                    all = false;
14968                }
14969            }
14970        }
14971
14972        int build(String[] args, int opti) {
14973            for (; opti<args.length; opti++) {
14974                String name = args[opti];
14975                if ("--".equals(name)) {
14976                    return opti+1;
14977                }
14978                build(name);
14979            }
14980            return opti;
14981        }
14982
14983        boolean match(Object object, ComponentName comp) {
14984            if (all) {
14985                return true;
14986            }
14987            if (components != null) {
14988                for (int i=0; i<components.size(); i++) {
14989                    if (components.get(i).equals(comp)) {
14990                        return true;
14991                    }
14992                }
14993            }
14994            if (objects != null) {
14995                for (int i=0; i<objects.size(); i++) {
14996                    if (System.identityHashCode(object) == objects.get(i)) {
14997                        return true;
14998                    }
14999                }
15000            }
15001            if (strings != null) {
15002                String flat = comp.flattenToString();
15003                for (int i=0; i<strings.size(); i++) {
15004                    if (flat.contains(strings.get(i))) {
15005                        return true;
15006                    }
15007                }
15008            }
15009            return false;
15010        }
15011    }
15012
15013    /**
15014     * There are three things that cmd can be:
15015     *  - a flattened component name that matches an existing activity
15016     *  - the cmd arg isn't the flattened component name of an existing activity:
15017     *    dump all activity whose component contains the cmd as a substring
15018     *  - A hex number of the ActivityRecord object instance.
15019     */
15020    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15021            int opti, boolean dumpAll) {
15022        ArrayList<ActivityRecord> activities;
15023
15024        synchronized (this) {
15025            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15026        }
15027
15028        if (activities.size() <= 0) {
15029            return false;
15030        }
15031
15032        String[] newArgs = new String[args.length - opti];
15033        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15034
15035        TaskRecord lastTask = null;
15036        boolean needSep = false;
15037        for (int i=activities.size()-1; i>=0; i--) {
15038            ActivityRecord r = activities.get(i);
15039            if (needSep) {
15040                pw.println();
15041            }
15042            needSep = true;
15043            synchronized (this) {
15044                if (lastTask != r.task) {
15045                    lastTask = r.task;
15046                    pw.print("TASK "); pw.print(lastTask.affinity);
15047                            pw.print(" id="); pw.println(lastTask.taskId);
15048                    if (dumpAll) {
15049                        lastTask.dump(pw, "  ");
15050                    }
15051                }
15052            }
15053            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15054        }
15055        return true;
15056    }
15057
15058    /**
15059     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15060     * there is a thread associated with the activity.
15061     */
15062    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15063            final ActivityRecord r, String[] args, boolean dumpAll) {
15064        String innerPrefix = prefix + "  ";
15065        synchronized (this) {
15066            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15067                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15068                    pw.print(" pid=");
15069                    if (r.app != null) pw.println(r.app.pid);
15070                    else pw.println("(not running)");
15071            if (dumpAll) {
15072                r.dump(pw, innerPrefix);
15073            }
15074        }
15075        if (r.app != null && r.app.thread != null) {
15076            // flush anything that is already in the PrintWriter since the thread is going
15077            // to write to the file descriptor directly
15078            pw.flush();
15079            try {
15080                TransferPipe tp = new TransferPipe();
15081                try {
15082                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15083                            r.appToken, innerPrefix, args);
15084                    tp.go(fd);
15085                } finally {
15086                    tp.kill();
15087                }
15088            } catch (IOException e) {
15089                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15090            } catch (RemoteException e) {
15091                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15092            }
15093        }
15094    }
15095
15096    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15097            int opti, boolean dumpAll, String dumpPackage) {
15098        boolean needSep = false;
15099        boolean onlyHistory = false;
15100        boolean printedAnything = false;
15101
15102        if ("history".equals(dumpPackage)) {
15103            if (opti < args.length && "-s".equals(args[opti])) {
15104                dumpAll = false;
15105            }
15106            onlyHistory = true;
15107            dumpPackage = null;
15108        }
15109
15110        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15111        if (!onlyHistory && dumpAll) {
15112            if (mRegisteredReceivers.size() > 0) {
15113                boolean printed = false;
15114                Iterator it = mRegisteredReceivers.values().iterator();
15115                while (it.hasNext()) {
15116                    ReceiverList r = (ReceiverList)it.next();
15117                    if (dumpPackage != null && (r.app == null ||
15118                            !dumpPackage.equals(r.app.info.packageName))) {
15119                        continue;
15120                    }
15121                    if (!printed) {
15122                        pw.println("  Registered Receivers:");
15123                        needSep = true;
15124                        printed = true;
15125                        printedAnything = true;
15126                    }
15127                    pw.print("  * "); pw.println(r);
15128                    r.dump(pw, "    ");
15129                }
15130            }
15131
15132            if (mReceiverResolver.dump(pw, needSep ?
15133                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15134                    "    ", dumpPackage, false, false)) {
15135                needSep = true;
15136                printedAnything = true;
15137            }
15138        }
15139
15140        for (BroadcastQueue q : mBroadcastQueues) {
15141            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15142            printedAnything |= needSep;
15143        }
15144
15145        needSep = true;
15146
15147        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15148            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15149                if (needSep) {
15150                    pw.println();
15151                }
15152                needSep = true;
15153                printedAnything = true;
15154                pw.print("  Sticky broadcasts for user ");
15155                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15156                StringBuilder sb = new StringBuilder(128);
15157                for (Map.Entry<String, ArrayList<Intent>> ent
15158                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15159                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15160                    if (dumpAll) {
15161                        pw.println(":");
15162                        ArrayList<Intent> intents = ent.getValue();
15163                        final int N = intents.size();
15164                        for (int i=0; i<N; i++) {
15165                            sb.setLength(0);
15166                            sb.append("    Intent: ");
15167                            intents.get(i).toShortString(sb, false, true, false, false);
15168                            pw.println(sb.toString());
15169                            Bundle bundle = intents.get(i).getExtras();
15170                            if (bundle != null) {
15171                                pw.print("      ");
15172                                pw.println(bundle.toString());
15173                            }
15174                        }
15175                    } else {
15176                        pw.println("");
15177                    }
15178                }
15179            }
15180        }
15181
15182        if (!onlyHistory && dumpAll) {
15183            pw.println();
15184            for (BroadcastQueue queue : mBroadcastQueues) {
15185                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15186                        + queue.mBroadcastsScheduled);
15187            }
15188            pw.println("  mHandler:");
15189            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15190            needSep = true;
15191            printedAnything = true;
15192        }
15193
15194        if (!printedAnything) {
15195            pw.println("  (nothing)");
15196        }
15197    }
15198
15199    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15200            int opti, boolean dumpAll, String dumpPackage) {
15201        if (mCurBroadcastStats == null) {
15202            return;
15203        }
15204
15205        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15206        final long now = SystemClock.elapsedRealtime();
15207        if (mLastBroadcastStats != null) {
15208            pw.print("  Last stats (from ");
15209            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15210            pw.print(" to ");
15211            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15212            pw.print(", ");
15213            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15214                    - mLastBroadcastStats.mStartUptime, pw);
15215            pw.println(" uptime):");
15216            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15217                pw.println("    (nothing)");
15218            }
15219            pw.println();
15220        }
15221        pw.print("  Current stats (from ");
15222        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15223        pw.print(" to now, ");
15224        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15225                - mCurBroadcastStats.mStartUptime, pw);
15226        pw.println(" uptime):");
15227        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15228            pw.println("    (nothing)");
15229        }
15230    }
15231
15232    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15233            int opti, boolean fullCheckin, String dumpPackage) {
15234        if (mCurBroadcastStats == null) {
15235            return;
15236        }
15237
15238        if (mLastBroadcastStats != null) {
15239            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15240            if (fullCheckin) {
15241                mLastBroadcastStats = null;
15242                return;
15243            }
15244        }
15245        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15246        if (fullCheckin) {
15247            mCurBroadcastStats = null;
15248        }
15249    }
15250
15251    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15252            int opti, boolean dumpAll, String dumpPackage) {
15253        boolean needSep;
15254        boolean printedAnything = false;
15255
15256        ItemMatcher matcher = new ItemMatcher();
15257        matcher.build(args, opti);
15258
15259        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15260
15261        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15262        printedAnything |= needSep;
15263
15264        if (mLaunchingProviders.size() > 0) {
15265            boolean printed = false;
15266            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15267                ContentProviderRecord r = mLaunchingProviders.get(i);
15268                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15269                    continue;
15270                }
15271                if (!printed) {
15272                    if (needSep) pw.println();
15273                    needSep = true;
15274                    pw.println("  Launching content providers:");
15275                    printed = true;
15276                    printedAnything = true;
15277                }
15278                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15279                        pw.println(r);
15280            }
15281        }
15282
15283        if (!printedAnything) {
15284            pw.println("  (nothing)");
15285        }
15286    }
15287
15288    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15289            int opti, boolean dumpAll, String dumpPackage) {
15290        boolean needSep = false;
15291        boolean printedAnything = false;
15292
15293        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15294
15295        if (mGrantedUriPermissions.size() > 0) {
15296            boolean printed = false;
15297            int dumpUid = -2;
15298            if (dumpPackage != null) {
15299                try {
15300                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15301                            MATCH_UNINSTALLED_PACKAGES, 0);
15302                } catch (NameNotFoundException e) {
15303                    dumpUid = -1;
15304                }
15305            }
15306            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15307                int uid = mGrantedUriPermissions.keyAt(i);
15308                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15309                    continue;
15310                }
15311                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15312                if (!printed) {
15313                    if (needSep) pw.println();
15314                    needSep = true;
15315                    pw.println("  Granted Uri Permissions:");
15316                    printed = true;
15317                    printedAnything = true;
15318                }
15319                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15320                for (UriPermission perm : perms.values()) {
15321                    pw.print("    "); pw.println(perm);
15322                    if (dumpAll) {
15323                        perm.dump(pw, "      ");
15324                    }
15325                }
15326            }
15327        }
15328
15329        if (!printedAnything) {
15330            pw.println("  (nothing)");
15331        }
15332    }
15333
15334    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15335            int opti, boolean dumpAll, String dumpPackage) {
15336        boolean printed = false;
15337
15338        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15339
15340        if (mIntentSenderRecords.size() > 0) {
15341            Iterator<WeakReference<PendingIntentRecord>> it
15342                    = mIntentSenderRecords.values().iterator();
15343            while (it.hasNext()) {
15344                WeakReference<PendingIntentRecord> ref = it.next();
15345                PendingIntentRecord rec = ref != null ? ref.get(): null;
15346                if (dumpPackage != null && (rec == null
15347                        || !dumpPackage.equals(rec.key.packageName))) {
15348                    continue;
15349                }
15350                printed = true;
15351                if (rec != null) {
15352                    pw.print("  * "); pw.println(rec);
15353                    if (dumpAll) {
15354                        rec.dump(pw, "    ");
15355                    }
15356                } else {
15357                    pw.print("  * "); pw.println(ref);
15358                }
15359            }
15360        }
15361
15362        if (!printed) {
15363            pw.println("  (nothing)");
15364        }
15365    }
15366
15367    private static final int dumpProcessList(PrintWriter pw,
15368            ActivityManagerService service, List list,
15369            String prefix, String normalLabel, String persistentLabel,
15370            String dumpPackage) {
15371        int numPers = 0;
15372        final int N = list.size()-1;
15373        for (int i=N; i>=0; i--) {
15374            ProcessRecord r = (ProcessRecord)list.get(i);
15375            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15376                continue;
15377            }
15378            pw.println(String.format("%s%s #%2d: %s",
15379                    prefix, (r.persistent ? persistentLabel : normalLabel),
15380                    i, r.toString()));
15381            if (r.persistent) {
15382                numPers++;
15383            }
15384        }
15385        return numPers;
15386    }
15387
15388    private static final boolean dumpProcessOomList(PrintWriter pw,
15389            ActivityManagerService service, List<ProcessRecord> origList,
15390            String prefix, String normalLabel, String persistentLabel,
15391            boolean inclDetails, String dumpPackage) {
15392
15393        ArrayList<Pair<ProcessRecord, Integer>> list
15394                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15395        for (int i=0; i<origList.size(); i++) {
15396            ProcessRecord r = origList.get(i);
15397            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15398                continue;
15399            }
15400            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15401        }
15402
15403        if (list.size() <= 0) {
15404            return false;
15405        }
15406
15407        Comparator<Pair<ProcessRecord, Integer>> comparator
15408                = new Comparator<Pair<ProcessRecord, Integer>>() {
15409            @Override
15410            public int compare(Pair<ProcessRecord, Integer> object1,
15411                    Pair<ProcessRecord, Integer> object2) {
15412                if (object1.first.setAdj != object2.first.setAdj) {
15413                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15414                }
15415                if (object1.first.setProcState != object2.first.setProcState) {
15416                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15417                }
15418                if (object1.second.intValue() != object2.second.intValue()) {
15419                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15420                }
15421                return 0;
15422            }
15423        };
15424
15425        Collections.sort(list, comparator);
15426
15427        final long curRealtime = SystemClock.elapsedRealtime();
15428        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15429        final long curUptime = SystemClock.uptimeMillis();
15430        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15431
15432        for (int i=list.size()-1; i>=0; i--) {
15433            ProcessRecord r = list.get(i).first;
15434            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15435            char schedGroup;
15436            switch (r.setSchedGroup) {
15437                case ProcessList.SCHED_GROUP_BACKGROUND:
15438                    schedGroup = 'B';
15439                    break;
15440                case ProcessList.SCHED_GROUP_DEFAULT:
15441                    schedGroup = 'F';
15442                    break;
15443                case ProcessList.SCHED_GROUP_TOP_APP:
15444                    schedGroup = 'T';
15445                    break;
15446                default:
15447                    schedGroup = '?';
15448                    break;
15449            }
15450            char foreground;
15451            if (r.foregroundActivities) {
15452                foreground = 'A';
15453            } else if (r.foregroundServices) {
15454                foreground = 'S';
15455            } else {
15456                foreground = ' ';
15457            }
15458            String procState = ProcessList.makeProcStateString(r.curProcState);
15459            pw.print(prefix);
15460            pw.print(r.persistent ? persistentLabel : normalLabel);
15461            pw.print(" #");
15462            int num = (origList.size()-1)-list.get(i).second;
15463            if (num < 10) pw.print(' ');
15464            pw.print(num);
15465            pw.print(": ");
15466            pw.print(oomAdj);
15467            pw.print(' ');
15468            pw.print(schedGroup);
15469            pw.print('/');
15470            pw.print(foreground);
15471            pw.print('/');
15472            pw.print(procState);
15473            pw.print(" trm:");
15474            if (r.trimMemoryLevel < 10) pw.print(' ');
15475            pw.print(r.trimMemoryLevel);
15476            pw.print(' ');
15477            pw.print(r.toShortString());
15478            pw.print(" (");
15479            pw.print(r.adjType);
15480            pw.println(')');
15481            if (r.adjSource != null || r.adjTarget != null) {
15482                pw.print(prefix);
15483                pw.print("    ");
15484                if (r.adjTarget instanceof ComponentName) {
15485                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15486                } else if (r.adjTarget != null) {
15487                    pw.print(r.adjTarget.toString());
15488                } else {
15489                    pw.print("{null}");
15490                }
15491                pw.print("<=");
15492                if (r.adjSource instanceof ProcessRecord) {
15493                    pw.print("Proc{");
15494                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15495                    pw.println("}");
15496                } else if (r.adjSource != null) {
15497                    pw.println(r.adjSource.toString());
15498                } else {
15499                    pw.println("{null}");
15500                }
15501            }
15502            if (inclDetails) {
15503                pw.print(prefix);
15504                pw.print("    ");
15505                pw.print("oom: max="); pw.print(r.maxAdj);
15506                pw.print(" curRaw="); pw.print(r.curRawAdj);
15507                pw.print(" setRaw="); pw.print(r.setRawAdj);
15508                pw.print(" cur="); pw.print(r.curAdj);
15509                pw.print(" set="); pw.println(r.setAdj);
15510                pw.print(prefix);
15511                pw.print("    ");
15512                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15513                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15514                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15515                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15516                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15517                pw.println();
15518                pw.print(prefix);
15519                pw.print("    ");
15520                pw.print("cached="); pw.print(r.cached);
15521                pw.print(" empty="); pw.print(r.empty);
15522                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15523
15524                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15525                    if (r.lastWakeTime != 0) {
15526                        long wtime;
15527                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15528                        synchronized (stats) {
15529                            wtime = stats.getProcessWakeTime(r.info.uid,
15530                                    r.pid, curRealtime);
15531                        }
15532                        long timeUsed = wtime - r.lastWakeTime;
15533                        pw.print(prefix);
15534                        pw.print("    ");
15535                        pw.print("keep awake over ");
15536                        TimeUtils.formatDuration(realtimeSince, pw);
15537                        pw.print(" used ");
15538                        TimeUtils.formatDuration(timeUsed, pw);
15539                        pw.print(" (");
15540                        pw.print((timeUsed*100)/realtimeSince);
15541                        pw.println("%)");
15542                    }
15543                    if (r.lastCpuTime != 0) {
15544                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15545                        pw.print(prefix);
15546                        pw.print("    ");
15547                        pw.print("run cpu over ");
15548                        TimeUtils.formatDuration(uptimeSince, pw);
15549                        pw.print(" used ");
15550                        TimeUtils.formatDuration(timeUsed, pw);
15551                        pw.print(" (");
15552                        pw.print((timeUsed*100)/uptimeSince);
15553                        pw.println("%)");
15554                    }
15555                }
15556            }
15557        }
15558        return true;
15559    }
15560
15561    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15562            String[] args) {
15563        ArrayList<ProcessRecord> procs;
15564        synchronized (this) {
15565            if (args != null && args.length > start
15566                    && args[start].charAt(0) != '-') {
15567                procs = new ArrayList<ProcessRecord>();
15568                int pid = -1;
15569                try {
15570                    pid = Integer.parseInt(args[start]);
15571                } catch (NumberFormatException e) {
15572                }
15573                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15574                    ProcessRecord proc = mLruProcesses.get(i);
15575                    if (proc.pid == pid) {
15576                        procs.add(proc);
15577                    } else if (allPkgs && proc.pkgList != null
15578                            && proc.pkgList.containsKey(args[start])) {
15579                        procs.add(proc);
15580                    } else if (proc.processName.equals(args[start])) {
15581                        procs.add(proc);
15582                    }
15583                }
15584                if (procs.size() <= 0) {
15585                    return null;
15586                }
15587            } else {
15588                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15589            }
15590        }
15591        return procs;
15592    }
15593
15594    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15595            PrintWriter pw, String[] args) {
15596        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15597        if (procs == null) {
15598            pw.println("No process found for: " + args[0]);
15599            return;
15600        }
15601
15602        long uptime = SystemClock.uptimeMillis();
15603        long realtime = SystemClock.elapsedRealtime();
15604        pw.println("Applications Graphics Acceleration Info:");
15605        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15606
15607        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15608            ProcessRecord r = procs.get(i);
15609            if (r.thread != null) {
15610                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15611                pw.flush();
15612                try {
15613                    TransferPipe tp = new TransferPipe();
15614                    try {
15615                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15616                        tp.go(fd);
15617                    } finally {
15618                        tp.kill();
15619                    }
15620                } catch (IOException e) {
15621                    pw.println("Failure while dumping the app: " + r);
15622                    pw.flush();
15623                } catch (RemoteException e) {
15624                    pw.println("Got a RemoteException while dumping the app " + r);
15625                    pw.flush();
15626                }
15627            }
15628        }
15629    }
15630
15631    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15632        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15633        if (procs == null) {
15634            pw.println("No process found for: " + args[0]);
15635            return;
15636        }
15637
15638        pw.println("Applications Database Info:");
15639
15640        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15641            ProcessRecord r = procs.get(i);
15642            if (r.thread != null) {
15643                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15644                pw.flush();
15645                try {
15646                    TransferPipe tp = new TransferPipe();
15647                    try {
15648                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15649                        tp.go(fd);
15650                    } finally {
15651                        tp.kill();
15652                    }
15653                } catch (IOException e) {
15654                    pw.println("Failure while dumping the app: " + r);
15655                    pw.flush();
15656                } catch (RemoteException e) {
15657                    pw.println("Got a RemoteException while dumping the app " + r);
15658                    pw.flush();
15659                }
15660            }
15661        }
15662    }
15663
15664    final static class MemItem {
15665        final boolean isProc;
15666        final String label;
15667        final String shortLabel;
15668        final long pss;
15669        final long swapPss;
15670        final int id;
15671        final boolean hasActivities;
15672        ArrayList<MemItem> subitems;
15673
15674        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15675                boolean _hasActivities) {
15676            isProc = true;
15677            label = _label;
15678            shortLabel = _shortLabel;
15679            pss = _pss;
15680            swapPss = _swapPss;
15681            id = _id;
15682            hasActivities = _hasActivities;
15683        }
15684
15685        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15686            isProc = false;
15687            label = _label;
15688            shortLabel = _shortLabel;
15689            pss = _pss;
15690            swapPss = _swapPss;
15691            id = _id;
15692            hasActivities = false;
15693        }
15694    }
15695
15696    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15697            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15698        if (sort && !isCompact) {
15699            Collections.sort(items, new Comparator<MemItem>() {
15700                @Override
15701                public int compare(MemItem lhs, MemItem rhs) {
15702                    if (lhs.pss < rhs.pss) {
15703                        return 1;
15704                    } else if (lhs.pss > rhs.pss) {
15705                        return -1;
15706                    }
15707                    return 0;
15708                }
15709            });
15710        }
15711
15712        for (int i=0; i<items.size(); i++) {
15713            MemItem mi = items.get(i);
15714            if (!isCompact) {
15715                if (dumpSwapPss) {
15716                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15717                            mi.label, stringifyKBSize(mi.swapPss));
15718                } else {
15719                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15720                }
15721            } else if (mi.isProc) {
15722                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15723                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15724                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15725                pw.println(mi.hasActivities ? ",a" : ",e");
15726            } else {
15727                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15728                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15729            }
15730            if (mi.subitems != null) {
15731                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15732                        true, isCompact, dumpSwapPss);
15733            }
15734        }
15735    }
15736
15737    // These are in KB.
15738    static final long[] DUMP_MEM_BUCKETS = new long[] {
15739        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15740        120*1024, 160*1024, 200*1024,
15741        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15742        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15743    };
15744
15745    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15746            boolean stackLike) {
15747        int start = label.lastIndexOf('.');
15748        if (start >= 0) start++;
15749        else start = 0;
15750        int end = label.length();
15751        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15752            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15753                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15754                out.append(bucket);
15755                out.append(stackLike ? "MB." : "MB ");
15756                out.append(label, start, end);
15757                return;
15758            }
15759        }
15760        out.append(memKB/1024);
15761        out.append(stackLike ? "MB." : "MB ");
15762        out.append(label, start, end);
15763    }
15764
15765    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15766            ProcessList.NATIVE_ADJ,
15767            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15768            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15769            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15770            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15771            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15772            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15773    };
15774    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15775            "Native",
15776            "System", "Persistent", "Persistent Service", "Foreground",
15777            "Visible", "Perceptible",
15778            "Heavy Weight", "Backup",
15779            "A Services", "Home",
15780            "Previous", "B Services", "Cached"
15781    };
15782    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15783            "native",
15784            "sys", "pers", "persvc", "fore",
15785            "vis", "percept",
15786            "heavy", "backup",
15787            "servicea", "home",
15788            "prev", "serviceb", "cached"
15789    };
15790
15791    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15792            long realtime, boolean isCheckinRequest, boolean isCompact) {
15793        if (isCompact) {
15794            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15795        }
15796        if (isCheckinRequest || isCompact) {
15797            // short checkin version
15798            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15799        } else {
15800            pw.println("Applications Memory Usage (in Kilobytes):");
15801            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15802        }
15803    }
15804
15805    private static final int KSM_SHARED = 0;
15806    private static final int KSM_SHARING = 1;
15807    private static final int KSM_UNSHARED = 2;
15808    private static final int KSM_VOLATILE = 3;
15809
15810    private final long[] getKsmInfo() {
15811        long[] longOut = new long[4];
15812        final int[] SINGLE_LONG_FORMAT = new int[] {
15813            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15814        };
15815        long[] longTmp = new long[1];
15816        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15817                SINGLE_LONG_FORMAT, null, longTmp, null);
15818        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15819        longTmp[0] = 0;
15820        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15821                SINGLE_LONG_FORMAT, null, longTmp, null);
15822        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15823        longTmp[0] = 0;
15824        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15825                SINGLE_LONG_FORMAT, null, longTmp, null);
15826        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15827        longTmp[0] = 0;
15828        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15829                SINGLE_LONG_FORMAT, null, longTmp, null);
15830        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15831        return longOut;
15832    }
15833
15834    private static String stringifySize(long size, int order) {
15835        Locale locale = Locale.US;
15836        switch (order) {
15837            case 1:
15838                return String.format(locale, "%,13d", size);
15839            case 1024:
15840                return String.format(locale, "%,9dK", size / 1024);
15841            case 1024 * 1024:
15842                return String.format(locale, "%,5dM", size / 1024 / 1024);
15843            case 1024 * 1024 * 1024:
15844                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15845            default:
15846                throw new IllegalArgumentException("Invalid size order");
15847        }
15848    }
15849
15850    private static String stringifyKBSize(long size) {
15851        return stringifySize(size * 1024, 1024);
15852    }
15853
15854    // Update this version number in case you change the 'compact' format
15855    private static final int MEMINFO_COMPACT_VERSION = 1;
15856
15857    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15858            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15859        boolean dumpDetails = false;
15860        boolean dumpFullDetails = false;
15861        boolean dumpDalvik = false;
15862        boolean dumpSummaryOnly = false;
15863        boolean dumpUnreachable = false;
15864        boolean oomOnly = false;
15865        boolean isCompact = false;
15866        boolean localOnly = false;
15867        boolean packages = false;
15868        boolean isCheckinRequest = false;
15869        boolean dumpSwapPss = false;
15870
15871        int opti = 0;
15872        while (opti < args.length) {
15873            String opt = args[opti];
15874            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15875                break;
15876            }
15877            opti++;
15878            if ("-a".equals(opt)) {
15879                dumpDetails = true;
15880                dumpFullDetails = true;
15881                dumpDalvik = true;
15882                dumpSwapPss = true;
15883            } else if ("-d".equals(opt)) {
15884                dumpDalvik = true;
15885            } else if ("-c".equals(opt)) {
15886                isCompact = true;
15887            } else if ("-s".equals(opt)) {
15888                dumpDetails = true;
15889                dumpSummaryOnly = true;
15890            } else if ("-S".equals(opt)) {
15891                dumpSwapPss = true;
15892            } else if ("--unreachable".equals(opt)) {
15893                dumpUnreachable = true;
15894            } else if ("--oom".equals(opt)) {
15895                oomOnly = true;
15896            } else if ("--local".equals(opt)) {
15897                localOnly = true;
15898            } else if ("--package".equals(opt)) {
15899                packages = true;
15900            } else if ("--checkin".equals(opt)) {
15901                isCheckinRequest = true;
15902
15903            } else if ("-h".equals(opt)) {
15904                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15905                pw.println("  -a: include all available information for each process.");
15906                pw.println("  -d: include dalvik details.");
15907                pw.println("  -c: dump in a compact machine-parseable representation.");
15908                pw.println("  -s: dump only summary of application memory usage.");
15909                pw.println("  -S: dump also SwapPss.");
15910                pw.println("  --oom: only show processes organized by oom adj.");
15911                pw.println("  --local: only collect details locally, don't call process.");
15912                pw.println("  --package: interpret process arg as package, dumping all");
15913                pw.println("             processes that have loaded that package.");
15914                pw.println("  --checkin: dump data for a checkin");
15915                pw.println("If [process] is specified it can be the name or ");
15916                pw.println("pid of a specific process to dump.");
15917                return;
15918            } else {
15919                pw.println("Unknown argument: " + opt + "; use -h for help");
15920            }
15921        }
15922
15923        long uptime = SystemClock.uptimeMillis();
15924        long realtime = SystemClock.elapsedRealtime();
15925        final long[] tmpLong = new long[1];
15926
15927        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15928        if (procs == null) {
15929            // No Java processes.  Maybe they want to print a native process.
15930            if (args != null && args.length > opti
15931                    && args[opti].charAt(0) != '-') {
15932                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15933                        = new ArrayList<ProcessCpuTracker.Stats>();
15934                updateCpuStatsNow();
15935                int findPid = -1;
15936                try {
15937                    findPid = Integer.parseInt(args[opti]);
15938                } catch (NumberFormatException e) {
15939                }
15940                synchronized (mProcessCpuTracker) {
15941                    final int N = mProcessCpuTracker.countStats();
15942                    for (int i=0; i<N; i++) {
15943                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15944                        if (st.pid == findPid || (st.baseName != null
15945                                && st.baseName.equals(args[opti]))) {
15946                            nativeProcs.add(st);
15947                        }
15948                    }
15949                }
15950                if (nativeProcs.size() > 0) {
15951                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15952                            isCompact);
15953                    Debug.MemoryInfo mi = null;
15954                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15955                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15956                        final int pid = r.pid;
15957                        if (!isCheckinRequest && dumpDetails) {
15958                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15959                        }
15960                        if (mi == null) {
15961                            mi = new Debug.MemoryInfo();
15962                        }
15963                        if (dumpDetails || (!brief && !oomOnly)) {
15964                            Debug.getMemoryInfo(pid, mi);
15965                        } else {
15966                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15967                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15968                        }
15969                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15970                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15971                        if (isCheckinRequest) {
15972                            pw.println();
15973                        }
15974                    }
15975                    return;
15976                }
15977            }
15978            pw.println("No process found for: " + args[opti]);
15979            return;
15980        }
15981
15982        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15983            dumpDetails = true;
15984        }
15985
15986        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15987
15988        String[] innerArgs = new String[args.length-opti];
15989        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15990
15991        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15992        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15993        long nativePss = 0;
15994        long nativeSwapPss = 0;
15995        long dalvikPss = 0;
15996        long dalvikSwapPss = 0;
15997        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15998                EmptyArray.LONG;
15999        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16000                EmptyArray.LONG;
16001        long otherPss = 0;
16002        long otherSwapPss = 0;
16003        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16004        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16005
16006        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16007        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16008        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16009                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16010
16011        long totalPss = 0;
16012        long totalSwapPss = 0;
16013        long cachedPss = 0;
16014        long cachedSwapPss = 0;
16015        boolean hasSwapPss = false;
16016
16017        Debug.MemoryInfo mi = null;
16018        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16019            final ProcessRecord r = procs.get(i);
16020            final IApplicationThread thread;
16021            final int pid;
16022            final int oomAdj;
16023            final boolean hasActivities;
16024            synchronized (this) {
16025                thread = r.thread;
16026                pid = r.pid;
16027                oomAdj = r.getSetAdjWithServices();
16028                hasActivities = r.activities.size() > 0;
16029            }
16030            if (thread != null) {
16031                if (!isCheckinRequest && dumpDetails) {
16032                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16033                }
16034                if (mi == null) {
16035                    mi = new Debug.MemoryInfo();
16036                }
16037                if (dumpDetails || (!brief && !oomOnly)) {
16038                    Debug.getMemoryInfo(pid, mi);
16039                    hasSwapPss = mi.hasSwappedOutPss;
16040                } else {
16041                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16042                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16043                }
16044                if (dumpDetails) {
16045                    if (localOnly) {
16046                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16047                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16048                        if (isCheckinRequest) {
16049                            pw.println();
16050                        }
16051                    } else {
16052                        try {
16053                            pw.flush();
16054                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16055                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16056                        } catch (RemoteException e) {
16057                            if (!isCheckinRequest) {
16058                                pw.println("Got RemoteException!");
16059                                pw.flush();
16060                            }
16061                        }
16062                    }
16063                }
16064
16065                final long myTotalPss = mi.getTotalPss();
16066                final long myTotalUss = mi.getTotalUss();
16067                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16068
16069                synchronized (this) {
16070                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16071                        // Record this for posterity if the process has been stable.
16072                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16073                    }
16074                }
16075
16076                if (!isCheckinRequest && mi != null) {
16077                    totalPss += myTotalPss;
16078                    totalSwapPss += myTotalSwapPss;
16079                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16080                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16081                            myTotalSwapPss, pid, hasActivities);
16082                    procMems.add(pssItem);
16083                    procMemsMap.put(pid, pssItem);
16084
16085                    nativePss += mi.nativePss;
16086                    nativeSwapPss += mi.nativeSwappedOutPss;
16087                    dalvikPss += mi.dalvikPss;
16088                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16089                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16090                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16091                        dalvikSubitemSwapPss[j] +=
16092                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16093                    }
16094                    otherPss += mi.otherPss;
16095                    otherSwapPss += mi.otherSwappedOutPss;
16096                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16097                        long mem = mi.getOtherPss(j);
16098                        miscPss[j] += mem;
16099                        otherPss -= mem;
16100                        mem = mi.getOtherSwappedOutPss(j);
16101                        miscSwapPss[j] += mem;
16102                        otherSwapPss -= mem;
16103                    }
16104
16105                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16106                        cachedPss += myTotalPss;
16107                        cachedSwapPss += myTotalSwapPss;
16108                    }
16109
16110                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16111                        if (oomIndex == (oomPss.length - 1)
16112                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16113                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16114                            oomPss[oomIndex] += myTotalPss;
16115                            oomSwapPss[oomIndex] += myTotalSwapPss;
16116                            if (oomProcs[oomIndex] == null) {
16117                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16118                            }
16119                            oomProcs[oomIndex].add(pssItem);
16120                            break;
16121                        }
16122                    }
16123                }
16124            }
16125        }
16126
16127        long nativeProcTotalPss = 0;
16128
16129        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16130            // If we are showing aggregations, also look for native processes to
16131            // include so that our aggregations are more accurate.
16132            updateCpuStatsNow();
16133            mi = null;
16134            synchronized (mProcessCpuTracker) {
16135                final int N = mProcessCpuTracker.countStats();
16136                for (int i=0; i<N; i++) {
16137                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16138                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16139                        if (mi == null) {
16140                            mi = new Debug.MemoryInfo();
16141                        }
16142                        if (!brief && !oomOnly) {
16143                            Debug.getMemoryInfo(st.pid, mi);
16144                        } else {
16145                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16146                            mi.nativePrivateDirty = (int)tmpLong[0];
16147                        }
16148
16149                        final long myTotalPss = mi.getTotalPss();
16150                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16151                        totalPss += myTotalPss;
16152                        nativeProcTotalPss += myTotalPss;
16153
16154                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16155                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16156                        procMems.add(pssItem);
16157
16158                        nativePss += mi.nativePss;
16159                        nativeSwapPss += mi.nativeSwappedOutPss;
16160                        dalvikPss += mi.dalvikPss;
16161                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16162                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16163                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16164                            dalvikSubitemSwapPss[j] +=
16165                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16166                        }
16167                        otherPss += mi.otherPss;
16168                        otherSwapPss += mi.otherSwappedOutPss;
16169                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16170                            long mem = mi.getOtherPss(j);
16171                            miscPss[j] += mem;
16172                            otherPss -= mem;
16173                            mem = mi.getOtherSwappedOutPss(j);
16174                            miscSwapPss[j] += mem;
16175                            otherSwapPss -= mem;
16176                        }
16177                        oomPss[0] += myTotalPss;
16178                        oomSwapPss[0] += myTotalSwapPss;
16179                        if (oomProcs[0] == null) {
16180                            oomProcs[0] = new ArrayList<MemItem>();
16181                        }
16182                        oomProcs[0].add(pssItem);
16183                    }
16184                }
16185            }
16186
16187            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16188
16189            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16190            final MemItem dalvikItem =
16191                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16192            if (dalvikSubitemPss.length > 0) {
16193                dalvikItem.subitems = new ArrayList<MemItem>();
16194                for (int j=0; j<dalvikSubitemPss.length; j++) {
16195                    final String name = Debug.MemoryInfo.getOtherLabel(
16196                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16197                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16198                                    dalvikSubitemSwapPss[j], j));
16199                }
16200            }
16201            catMems.add(dalvikItem);
16202            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16203            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16204                String label = Debug.MemoryInfo.getOtherLabel(j);
16205                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16206            }
16207
16208            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16209            for (int j=0; j<oomPss.length; j++) {
16210                if (oomPss[j] != 0) {
16211                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16212                            : DUMP_MEM_OOM_LABEL[j];
16213                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16214                            DUMP_MEM_OOM_ADJ[j]);
16215                    item.subitems = oomProcs[j];
16216                    oomMems.add(item);
16217                }
16218            }
16219
16220            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16221            if (!brief && !oomOnly && !isCompact) {
16222                pw.println();
16223                pw.println("Total PSS by process:");
16224                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16225                pw.println();
16226            }
16227            if (!isCompact) {
16228                pw.println("Total PSS by OOM adjustment:");
16229            }
16230            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16231            if (!brief && !oomOnly) {
16232                PrintWriter out = categoryPw != null ? categoryPw : pw;
16233                if (!isCompact) {
16234                    out.println();
16235                    out.println("Total PSS by category:");
16236                }
16237                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16238            }
16239            if (!isCompact) {
16240                pw.println();
16241            }
16242            MemInfoReader memInfo = new MemInfoReader();
16243            memInfo.readMemInfo();
16244            if (nativeProcTotalPss > 0) {
16245                synchronized (this) {
16246                    final long cachedKb = memInfo.getCachedSizeKb();
16247                    final long freeKb = memInfo.getFreeSizeKb();
16248                    final long zramKb = memInfo.getZramTotalSizeKb();
16249                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16250                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16251                            kernelKb*1024, nativeProcTotalPss*1024);
16252                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16253                            nativeProcTotalPss);
16254                }
16255            }
16256            if (!brief) {
16257                if (!isCompact) {
16258                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16259                    pw.print(" (status ");
16260                    switch (mLastMemoryLevel) {
16261                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16262                            pw.println("normal)");
16263                            break;
16264                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16265                            pw.println("moderate)");
16266                            break;
16267                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16268                            pw.println("low)");
16269                            break;
16270                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16271                            pw.println("critical)");
16272                            break;
16273                        default:
16274                            pw.print(mLastMemoryLevel);
16275                            pw.println(")");
16276                            break;
16277                    }
16278                    pw.print(" Free RAM: ");
16279                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16280                            + memInfo.getFreeSizeKb()));
16281                    pw.print(" (");
16282                    pw.print(stringifyKBSize(cachedPss));
16283                    pw.print(" cached pss + ");
16284                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16285                    pw.print(" cached kernel + ");
16286                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16287                    pw.println(" free)");
16288                } else {
16289                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16290                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16291                            + memInfo.getFreeSizeKb()); pw.print(",");
16292                    pw.println(totalPss - cachedPss);
16293                }
16294            }
16295            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16296                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16297                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16298            if (!isCompact) {
16299                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16300                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16301                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16302                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16303                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16304            } else {
16305                pw.print("lostram,"); pw.println(lostRAM);
16306            }
16307            if (!brief) {
16308                if (memInfo.getZramTotalSizeKb() != 0) {
16309                    if (!isCompact) {
16310                        pw.print("     ZRAM: ");
16311                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16312                                pw.print(" physical used for ");
16313                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16314                                        - memInfo.getSwapFreeSizeKb()));
16315                                pw.print(" in swap (");
16316                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16317                                pw.println(" total swap)");
16318                    } else {
16319                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16320                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16321                                pw.println(memInfo.getSwapFreeSizeKb());
16322                    }
16323                }
16324                final long[] ksm = getKsmInfo();
16325                if (!isCompact) {
16326                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16327                            || ksm[KSM_VOLATILE] != 0) {
16328                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16329                                pw.print(" saved from shared ");
16330                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16331                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16332                                pw.print(" unshared; ");
16333                                pw.print(stringifyKBSize(
16334                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16335                    }
16336                    pw.print("   Tuning: ");
16337                    pw.print(ActivityManager.staticGetMemoryClass());
16338                    pw.print(" (large ");
16339                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16340                    pw.print("), oom ");
16341                    pw.print(stringifySize(
16342                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16343                    pw.print(", restore limit ");
16344                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16345                    if (ActivityManager.isLowRamDeviceStatic()) {
16346                        pw.print(" (low-ram)");
16347                    }
16348                    if (ActivityManager.isHighEndGfx()) {
16349                        pw.print(" (high-end-gfx)");
16350                    }
16351                    pw.println();
16352                } else {
16353                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16354                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16355                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16356                    pw.print("tuning,");
16357                    pw.print(ActivityManager.staticGetMemoryClass());
16358                    pw.print(',');
16359                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16360                    pw.print(',');
16361                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16362                    if (ActivityManager.isLowRamDeviceStatic()) {
16363                        pw.print(",low-ram");
16364                    }
16365                    if (ActivityManager.isHighEndGfx()) {
16366                        pw.print(",high-end-gfx");
16367                    }
16368                    pw.println();
16369                }
16370            }
16371        }
16372    }
16373
16374    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16375            long memtrack, String name) {
16376        sb.append("  ");
16377        sb.append(ProcessList.makeOomAdjString(oomAdj));
16378        sb.append(' ');
16379        sb.append(ProcessList.makeProcStateString(procState));
16380        sb.append(' ');
16381        ProcessList.appendRamKb(sb, pss);
16382        sb.append(": ");
16383        sb.append(name);
16384        if (memtrack > 0) {
16385            sb.append(" (");
16386            sb.append(stringifyKBSize(memtrack));
16387            sb.append(" memtrack)");
16388        }
16389    }
16390
16391    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16392        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16393        sb.append(" (pid ");
16394        sb.append(mi.pid);
16395        sb.append(") ");
16396        sb.append(mi.adjType);
16397        sb.append('\n');
16398        if (mi.adjReason != null) {
16399            sb.append("                      ");
16400            sb.append(mi.adjReason);
16401            sb.append('\n');
16402        }
16403    }
16404
16405    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16406        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16407        for (int i=0, N=memInfos.size(); i<N; i++) {
16408            ProcessMemInfo mi = memInfos.get(i);
16409            infoMap.put(mi.pid, mi);
16410        }
16411        updateCpuStatsNow();
16412        long[] memtrackTmp = new long[1];
16413        synchronized (mProcessCpuTracker) {
16414            final int N = mProcessCpuTracker.countStats();
16415            for (int i=0; i<N; i++) {
16416                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16417                if (st.vsize > 0) {
16418                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16419                    if (pss > 0) {
16420                        if (infoMap.indexOfKey(st.pid) < 0) {
16421                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16422                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16423                            mi.pss = pss;
16424                            mi.memtrack = memtrackTmp[0];
16425                            memInfos.add(mi);
16426                        }
16427                    }
16428                }
16429            }
16430        }
16431
16432        long totalPss = 0;
16433        long totalMemtrack = 0;
16434        for (int i=0, N=memInfos.size(); i<N; i++) {
16435            ProcessMemInfo mi = memInfos.get(i);
16436            if (mi.pss == 0) {
16437                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16438                mi.memtrack = memtrackTmp[0];
16439            }
16440            totalPss += mi.pss;
16441            totalMemtrack += mi.memtrack;
16442        }
16443        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16444            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16445                if (lhs.oomAdj != rhs.oomAdj) {
16446                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16447                }
16448                if (lhs.pss != rhs.pss) {
16449                    return lhs.pss < rhs.pss ? 1 : -1;
16450                }
16451                return 0;
16452            }
16453        });
16454
16455        StringBuilder tag = new StringBuilder(128);
16456        StringBuilder stack = new StringBuilder(128);
16457        tag.append("Low on memory -- ");
16458        appendMemBucket(tag, totalPss, "total", false);
16459        appendMemBucket(stack, totalPss, "total", true);
16460
16461        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16462        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16463        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16464
16465        boolean firstLine = true;
16466        int lastOomAdj = Integer.MIN_VALUE;
16467        long extraNativeRam = 0;
16468        long extraNativeMemtrack = 0;
16469        long cachedPss = 0;
16470        for (int i=0, N=memInfos.size(); i<N; i++) {
16471            ProcessMemInfo mi = memInfos.get(i);
16472
16473            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16474                cachedPss += mi.pss;
16475            }
16476
16477            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16478                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16479                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16480                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16481                if (lastOomAdj != mi.oomAdj) {
16482                    lastOomAdj = mi.oomAdj;
16483                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16484                        tag.append(" / ");
16485                    }
16486                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16487                        if (firstLine) {
16488                            stack.append(":");
16489                            firstLine = false;
16490                        }
16491                        stack.append("\n\t at ");
16492                    } else {
16493                        stack.append("$");
16494                    }
16495                } else {
16496                    tag.append(" ");
16497                    stack.append("$");
16498                }
16499                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16500                    appendMemBucket(tag, mi.pss, mi.name, false);
16501                }
16502                appendMemBucket(stack, mi.pss, mi.name, true);
16503                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16504                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16505                    stack.append("(");
16506                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16507                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16508                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16509                            stack.append(":");
16510                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16511                        }
16512                    }
16513                    stack.append(")");
16514                }
16515            }
16516
16517            appendMemInfo(fullNativeBuilder, mi);
16518            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16519                // The short form only has native processes that are >= 512K.
16520                if (mi.pss >= 512) {
16521                    appendMemInfo(shortNativeBuilder, mi);
16522                } else {
16523                    extraNativeRam += mi.pss;
16524                    extraNativeMemtrack += mi.memtrack;
16525                }
16526            } else {
16527                // Short form has all other details, but if we have collected RAM
16528                // from smaller native processes let's dump a summary of that.
16529                if (extraNativeRam > 0) {
16530                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16531                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16532                    shortNativeBuilder.append('\n');
16533                    extraNativeRam = 0;
16534                }
16535                appendMemInfo(fullJavaBuilder, mi);
16536            }
16537        }
16538
16539        fullJavaBuilder.append("           ");
16540        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16541        fullJavaBuilder.append(": TOTAL");
16542        if (totalMemtrack > 0) {
16543            fullJavaBuilder.append(" (");
16544            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16545            fullJavaBuilder.append(" memtrack)");
16546        } else {
16547        }
16548        fullJavaBuilder.append("\n");
16549
16550        MemInfoReader memInfo = new MemInfoReader();
16551        memInfo.readMemInfo();
16552        final long[] infos = memInfo.getRawInfo();
16553
16554        StringBuilder memInfoBuilder = new StringBuilder(1024);
16555        Debug.getMemInfo(infos);
16556        memInfoBuilder.append("  MemInfo: ");
16557        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16558        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16559        memInfoBuilder.append(stringifyKBSize(
16560                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16561        memInfoBuilder.append(stringifyKBSize(
16562                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16563        memInfoBuilder.append(stringifyKBSize(
16564                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16565        memInfoBuilder.append("           ");
16566        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16567        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16568        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16569        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16570        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16571            memInfoBuilder.append("  ZRAM: ");
16572            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16573            memInfoBuilder.append(" RAM, ");
16574            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16575            memInfoBuilder.append(" swap total, ");
16576            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16577            memInfoBuilder.append(" swap free\n");
16578        }
16579        final long[] ksm = getKsmInfo();
16580        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16581                || ksm[KSM_VOLATILE] != 0) {
16582            memInfoBuilder.append("  KSM: ");
16583            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16584            memInfoBuilder.append(" saved from shared ");
16585            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16586            memInfoBuilder.append("\n       ");
16587            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16588            memInfoBuilder.append(" unshared; ");
16589            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16590            memInfoBuilder.append(" volatile\n");
16591        }
16592        memInfoBuilder.append("  Free RAM: ");
16593        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16594                + memInfo.getFreeSizeKb()));
16595        memInfoBuilder.append("\n");
16596        memInfoBuilder.append("  Used RAM: ");
16597        memInfoBuilder.append(stringifyKBSize(
16598                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16599        memInfoBuilder.append("\n");
16600        memInfoBuilder.append("  Lost RAM: ");
16601        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16602                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16603                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16604        memInfoBuilder.append("\n");
16605        Slog.i(TAG, "Low on memory:");
16606        Slog.i(TAG, shortNativeBuilder.toString());
16607        Slog.i(TAG, fullJavaBuilder.toString());
16608        Slog.i(TAG, memInfoBuilder.toString());
16609
16610        StringBuilder dropBuilder = new StringBuilder(1024);
16611        /*
16612        StringWriter oomSw = new StringWriter();
16613        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16614        StringWriter catSw = new StringWriter();
16615        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16616        String[] emptyArgs = new String[] { };
16617        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16618        oomPw.flush();
16619        String oomString = oomSw.toString();
16620        */
16621        dropBuilder.append("Low on memory:");
16622        dropBuilder.append(stack);
16623        dropBuilder.append('\n');
16624        dropBuilder.append(fullNativeBuilder);
16625        dropBuilder.append(fullJavaBuilder);
16626        dropBuilder.append('\n');
16627        dropBuilder.append(memInfoBuilder);
16628        dropBuilder.append('\n');
16629        /*
16630        dropBuilder.append(oomString);
16631        dropBuilder.append('\n');
16632        */
16633        StringWriter catSw = new StringWriter();
16634        synchronized (ActivityManagerService.this) {
16635            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16636            String[] emptyArgs = new String[] { };
16637            catPw.println();
16638            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16639            catPw.println();
16640            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16641                    false, null).dumpLocked();
16642            catPw.println();
16643            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16644            catPw.flush();
16645        }
16646        dropBuilder.append(catSw.toString());
16647        addErrorToDropBox("lowmem", null, "system_server", null,
16648                null, tag.toString(), dropBuilder.toString(), null, null);
16649        //Slog.i(TAG, "Sent to dropbox:");
16650        //Slog.i(TAG, dropBuilder.toString());
16651        synchronized (ActivityManagerService.this) {
16652            long now = SystemClock.uptimeMillis();
16653            if (mLastMemUsageReportTime < now) {
16654                mLastMemUsageReportTime = now;
16655            }
16656        }
16657    }
16658
16659    /**
16660     * Searches array of arguments for the specified string
16661     * @param args array of argument strings
16662     * @param value value to search for
16663     * @return true if the value is contained in the array
16664     */
16665    private static boolean scanArgs(String[] args, String value) {
16666        if (args != null) {
16667            for (String arg : args) {
16668                if (value.equals(arg)) {
16669                    return true;
16670                }
16671            }
16672        }
16673        return false;
16674    }
16675
16676    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16677            ContentProviderRecord cpr, boolean always) {
16678        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16679
16680        if (!inLaunching || always) {
16681            synchronized (cpr) {
16682                cpr.launchingApp = null;
16683                cpr.notifyAll();
16684            }
16685            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16686            String names[] = cpr.info.authority.split(";");
16687            for (int j = 0; j < names.length; j++) {
16688                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16689            }
16690        }
16691
16692        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16693            ContentProviderConnection conn = cpr.connections.get(i);
16694            if (conn.waiting) {
16695                // If this connection is waiting for the provider, then we don't
16696                // need to mess with its process unless we are always removing
16697                // or for some reason the provider is not currently launching.
16698                if (inLaunching && !always) {
16699                    continue;
16700                }
16701            }
16702            ProcessRecord capp = conn.client;
16703            conn.dead = true;
16704            if (conn.stableCount > 0) {
16705                if (!capp.persistent && capp.thread != null
16706                        && capp.pid != 0
16707                        && capp.pid != MY_PID) {
16708                    capp.kill("depends on provider "
16709                            + cpr.name.flattenToShortString()
16710                            + " in dying proc " + (proc != null ? proc.processName : "??")
16711                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16712                }
16713            } else if (capp.thread != null && conn.provider.provider != null) {
16714                try {
16715                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16716                } catch (RemoteException e) {
16717                }
16718                // In the protocol here, we don't expect the client to correctly
16719                // clean up this connection, we'll just remove it.
16720                cpr.connections.remove(i);
16721                if (conn.client.conProviders.remove(conn)) {
16722                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16723                }
16724            }
16725        }
16726
16727        if (inLaunching && always) {
16728            mLaunchingProviders.remove(cpr);
16729        }
16730        return inLaunching;
16731    }
16732
16733    /**
16734     * Main code for cleaning up a process when it has gone away.  This is
16735     * called both as a result of the process dying, or directly when stopping
16736     * a process when running in single process mode.
16737     *
16738     * @return Returns true if the given process has been restarted, so the
16739     * app that was passed in must remain on the process lists.
16740     */
16741    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16742            boolean restarting, boolean allowRestart, int index) {
16743        if (index >= 0) {
16744            removeLruProcessLocked(app);
16745            ProcessList.remove(app.pid);
16746        }
16747
16748        mProcessesToGc.remove(app);
16749        mPendingPssProcesses.remove(app);
16750
16751        // Dismiss any open dialogs.
16752        if (app.crashDialog != null && !app.forceCrashReport) {
16753            app.crashDialog.dismiss();
16754            app.crashDialog = null;
16755        }
16756        if (app.anrDialog != null) {
16757            app.anrDialog.dismiss();
16758            app.anrDialog = null;
16759        }
16760        if (app.waitDialog != null) {
16761            app.waitDialog.dismiss();
16762            app.waitDialog = null;
16763        }
16764
16765        app.crashing = false;
16766        app.notResponding = false;
16767
16768        app.resetPackageList(mProcessStats);
16769        app.unlinkDeathRecipient();
16770        app.makeInactive(mProcessStats);
16771        app.waitingToKill = null;
16772        app.forcingToForeground = null;
16773        updateProcessForegroundLocked(app, false, false);
16774        app.foregroundActivities = false;
16775        app.hasShownUi = false;
16776        app.treatLikeActivity = false;
16777        app.hasAboveClient = false;
16778        app.hasClientActivities = false;
16779
16780        mServices.killServicesLocked(app, allowRestart);
16781
16782        boolean restart = false;
16783
16784        // Remove published content providers.
16785        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16786            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16787            final boolean always = app.bad || !allowRestart;
16788            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16789            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16790                // We left the provider in the launching list, need to
16791                // restart it.
16792                restart = true;
16793            }
16794
16795            cpr.provider = null;
16796            cpr.proc = null;
16797        }
16798        app.pubProviders.clear();
16799
16800        // Take care of any launching providers waiting for this process.
16801        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16802            restart = true;
16803        }
16804
16805        // Unregister from connected content providers.
16806        if (!app.conProviders.isEmpty()) {
16807            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16808                ContentProviderConnection conn = app.conProviders.get(i);
16809                conn.provider.connections.remove(conn);
16810                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16811                        conn.provider.name);
16812            }
16813            app.conProviders.clear();
16814        }
16815
16816        // At this point there may be remaining entries in mLaunchingProviders
16817        // where we were the only one waiting, so they are no longer of use.
16818        // Look for these and clean up if found.
16819        // XXX Commented out for now.  Trying to figure out a way to reproduce
16820        // the actual situation to identify what is actually going on.
16821        if (false) {
16822            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16823                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16824                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16825                    synchronized (cpr) {
16826                        cpr.launchingApp = null;
16827                        cpr.notifyAll();
16828                    }
16829                }
16830            }
16831        }
16832
16833        skipCurrentReceiverLocked(app);
16834
16835        // Unregister any receivers.
16836        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16837            removeReceiverLocked(app.receivers.valueAt(i));
16838        }
16839        app.receivers.clear();
16840
16841        // If the app is undergoing backup, tell the backup manager about it
16842        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16843            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16844                    + mBackupTarget.appInfo + " died during backup");
16845            try {
16846                IBackupManager bm = IBackupManager.Stub.asInterface(
16847                        ServiceManager.getService(Context.BACKUP_SERVICE));
16848                bm.agentDisconnected(app.info.packageName);
16849            } catch (RemoteException e) {
16850                // can't happen; backup manager is local
16851            }
16852        }
16853
16854        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16855            ProcessChangeItem item = mPendingProcessChanges.get(i);
16856            if (item.pid == app.pid) {
16857                mPendingProcessChanges.remove(i);
16858                mAvailProcessChanges.add(item);
16859            }
16860        }
16861        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16862                null).sendToTarget();
16863
16864        // If the caller is restarting this app, then leave it in its
16865        // current lists and let the caller take care of it.
16866        if (restarting) {
16867            return false;
16868        }
16869
16870        if (!app.persistent || app.isolated) {
16871            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16872                    "Removing non-persistent process during cleanup: " + app);
16873            removeProcessNameLocked(app.processName, app.uid);
16874            if (mHeavyWeightProcess == app) {
16875                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16876                        mHeavyWeightProcess.userId, 0));
16877                mHeavyWeightProcess = null;
16878            }
16879        } else if (!app.removed) {
16880            // This app is persistent, so we need to keep its record around.
16881            // If it is not already on the pending app list, add it there
16882            // and start a new process for it.
16883            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16884                mPersistentStartingProcesses.add(app);
16885                restart = true;
16886            }
16887        }
16888        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16889                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16890        mProcessesOnHold.remove(app);
16891
16892        if (app == mHomeProcess) {
16893            mHomeProcess = null;
16894        }
16895        if (app == mPreviousProcess) {
16896            mPreviousProcess = null;
16897        }
16898
16899        if (restart && !app.isolated) {
16900            // We have components that still need to be running in the
16901            // process, so re-launch it.
16902            if (index < 0) {
16903                ProcessList.remove(app.pid);
16904            }
16905            addProcessNameLocked(app);
16906            startProcessLocked(app, "restart", app.processName);
16907            return true;
16908        } else if (app.pid > 0 && app.pid != MY_PID) {
16909            // Goodbye!
16910            boolean removed;
16911            synchronized (mPidsSelfLocked) {
16912                mPidsSelfLocked.remove(app.pid);
16913                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16914            }
16915            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16916            if (app.isolated) {
16917                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16918            }
16919            app.setPid(0);
16920        }
16921        return false;
16922    }
16923
16924    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16925        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16926            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16927            if (cpr.launchingApp == app) {
16928                return true;
16929            }
16930        }
16931        return false;
16932    }
16933
16934    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16935        // Look through the content providers we are waiting to have launched,
16936        // and if any run in this process then either schedule a restart of
16937        // the process or kill the client waiting for it if this process has
16938        // gone bad.
16939        boolean restart = false;
16940        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16941            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16942            if (cpr.launchingApp == app) {
16943                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16944                    restart = true;
16945                } else {
16946                    removeDyingProviderLocked(app, cpr, true);
16947                }
16948            }
16949        }
16950        return restart;
16951    }
16952
16953    // =========================================================
16954    // SERVICES
16955    // =========================================================
16956
16957    @Override
16958    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16959            int flags) {
16960        enforceNotIsolatedCaller("getServices");
16961        synchronized (this) {
16962            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16963        }
16964    }
16965
16966    @Override
16967    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16968        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16969        synchronized (this) {
16970            return mServices.getRunningServiceControlPanelLocked(name);
16971        }
16972    }
16973
16974    @Override
16975    public ComponentName startService(IApplicationThread caller, Intent service,
16976            String resolvedType, String callingPackage, int userId)
16977            throws TransactionTooLargeException {
16978        enforceNotIsolatedCaller("startService");
16979        // Refuse possible leaked file descriptors
16980        if (service != null && service.hasFileDescriptors() == true) {
16981            throw new IllegalArgumentException("File descriptors passed in Intent");
16982        }
16983
16984        if (callingPackage == null) {
16985            throw new IllegalArgumentException("callingPackage cannot be null");
16986        }
16987
16988        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16989                "startService: " + service + " type=" + resolvedType);
16990        synchronized(this) {
16991            final int callingPid = Binder.getCallingPid();
16992            final int callingUid = Binder.getCallingUid();
16993            final long origId = Binder.clearCallingIdentity();
16994            ComponentName res = mServices.startServiceLocked(caller, service,
16995                    resolvedType, callingPid, callingUid, callingPackage, userId);
16996            Binder.restoreCallingIdentity(origId);
16997            return res;
16998        }
16999    }
17000
17001    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17002            String callingPackage, int userId)
17003            throws TransactionTooLargeException {
17004        synchronized(this) {
17005            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17006                    "startServiceInPackage: " + service + " type=" + resolvedType);
17007            final long origId = Binder.clearCallingIdentity();
17008            ComponentName res = mServices.startServiceLocked(null, service,
17009                    resolvedType, -1, uid, callingPackage, userId);
17010            Binder.restoreCallingIdentity(origId);
17011            return res;
17012        }
17013    }
17014
17015    @Override
17016    public int stopService(IApplicationThread caller, Intent service,
17017            String resolvedType, int userId) {
17018        enforceNotIsolatedCaller("stopService");
17019        // Refuse possible leaked file descriptors
17020        if (service != null && service.hasFileDescriptors() == true) {
17021            throw new IllegalArgumentException("File descriptors passed in Intent");
17022        }
17023
17024        synchronized(this) {
17025            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17026        }
17027    }
17028
17029    @Override
17030    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17031        enforceNotIsolatedCaller("peekService");
17032        // Refuse possible leaked file descriptors
17033        if (service != null && service.hasFileDescriptors() == true) {
17034            throw new IllegalArgumentException("File descriptors passed in Intent");
17035        }
17036
17037        if (callingPackage == null) {
17038            throw new IllegalArgumentException("callingPackage cannot be null");
17039        }
17040
17041        synchronized(this) {
17042            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17043        }
17044    }
17045
17046    @Override
17047    public boolean stopServiceToken(ComponentName className, IBinder token,
17048            int startId) {
17049        synchronized(this) {
17050            return mServices.stopServiceTokenLocked(className, token, startId);
17051        }
17052    }
17053
17054    @Override
17055    public void setServiceForeground(ComponentName className, IBinder token,
17056            int id, Notification notification, int flags) {
17057        synchronized(this) {
17058            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17059        }
17060    }
17061
17062    @Override
17063    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17064            boolean requireFull, String name, String callerPackage) {
17065        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17066                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17067    }
17068
17069    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17070            String className, int flags) {
17071        boolean result = false;
17072        // For apps that don't have pre-defined UIDs, check for permission
17073        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17074            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17075                if (ActivityManager.checkUidPermission(
17076                        INTERACT_ACROSS_USERS,
17077                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17078                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17079                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17080                            + " requests FLAG_SINGLE_USER, but app does not hold "
17081                            + INTERACT_ACROSS_USERS;
17082                    Slog.w(TAG, msg);
17083                    throw new SecurityException(msg);
17084                }
17085                // Permission passed
17086                result = true;
17087            }
17088        } else if ("system".equals(componentProcessName)) {
17089            result = true;
17090        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17091            // Phone app and persistent apps are allowed to export singleuser providers.
17092            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17093                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17094        }
17095        if (DEBUG_MU) Slog.v(TAG_MU,
17096                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17097                + Integer.toHexString(flags) + ") = " + result);
17098        return result;
17099    }
17100
17101    /**
17102     * Checks to see if the caller is in the same app as the singleton
17103     * component, or the component is in a special app. It allows special apps
17104     * to export singleton components but prevents exporting singleton
17105     * components for regular apps.
17106     */
17107    boolean isValidSingletonCall(int callingUid, int componentUid) {
17108        int componentAppId = UserHandle.getAppId(componentUid);
17109        return UserHandle.isSameApp(callingUid, componentUid)
17110                || componentAppId == Process.SYSTEM_UID
17111                || componentAppId == Process.PHONE_UID
17112                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17113                        == PackageManager.PERMISSION_GRANTED;
17114    }
17115
17116    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17117            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17118            int userId) throws TransactionTooLargeException {
17119        enforceNotIsolatedCaller("bindService");
17120
17121        // Refuse possible leaked file descriptors
17122        if (service != null && service.hasFileDescriptors() == true) {
17123            throw new IllegalArgumentException("File descriptors passed in Intent");
17124        }
17125
17126        if (callingPackage == null) {
17127            throw new IllegalArgumentException("callingPackage cannot be null");
17128        }
17129
17130        synchronized(this) {
17131            return mServices.bindServiceLocked(caller, token, service,
17132                    resolvedType, connection, flags, callingPackage, userId);
17133        }
17134    }
17135
17136    public boolean unbindService(IServiceConnection connection) {
17137        synchronized (this) {
17138            return mServices.unbindServiceLocked(connection);
17139        }
17140    }
17141
17142    public void publishService(IBinder token, Intent intent, IBinder service) {
17143        // Refuse possible leaked file descriptors
17144        if (intent != null && intent.hasFileDescriptors() == true) {
17145            throw new IllegalArgumentException("File descriptors passed in Intent");
17146        }
17147
17148        synchronized(this) {
17149            if (!(token instanceof ServiceRecord)) {
17150                throw new IllegalArgumentException("Invalid service token");
17151            }
17152            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17153        }
17154    }
17155
17156    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17157        // Refuse possible leaked file descriptors
17158        if (intent != null && intent.hasFileDescriptors() == true) {
17159            throw new IllegalArgumentException("File descriptors passed in Intent");
17160        }
17161
17162        synchronized(this) {
17163            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17164        }
17165    }
17166
17167    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17168        synchronized(this) {
17169            if (!(token instanceof ServiceRecord)) {
17170                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17171                throw new IllegalArgumentException("Invalid service token");
17172            }
17173            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17174        }
17175    }
17176
17177    // =========================================================
17178    // BACKUP AND RESTORE
17179    // =========================================================
17180
17181    // Cause the target app to be launched if necessary and its backup agent
17182    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17183    // activity manager to announce its creation.
17184    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17185        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17186        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17187
17188        IPackageManager pm = AppGlobals.getPackageManager();
17189        ApplicationInfo app = null;
17190        try {
17191            app = pm.getApplicationInfo(packageName, 0, userId);
17192        } catch (RemoteException e) {
17193            // can't happen; package manager is process-local
17194        }
17195        if (app == null) {
17196            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17197            return false;
17198        }
17199
17200        synchronized(this) {
17201            // !!! TODO: currently no check here that we're already bound
17202            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17203            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17204            synchronized (stats) {
17205                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17206            }
17207
17208            // Backup agent is now in use, its package can't be stopped.
17209            try {
17210                AppGlobals.getPackageManager().setPackageStoppedState(
17211                        app.packageName, false, UserHandle.getUserId(app.uid));
17212            } catch (RemoteException e) {
17213            } catch (IllegalArgumentException e) {
17214                Slog.w(TAG, "Failed trying to unstop package "
17215                        + app.packageName + ": " + e);
17216            }
17217
17218            BackupRecord r = new BackupRecord(ss, app, backupMode);
17219            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17220                    ? new ComponentName(app.packageName, app.backupAgentName)
17221                    : new ComponentName("android", "FullBackupAgent");
17222            // startProcessLocked() returns existing proc's record if it's already running
17223            ProcessRecord proc = startProcessLocked(app.processName, app,
17224                    false, 0, "backup", hostingName, false, false, false);
17225            if (proc == null) {
17226                Slog.e(TAG, "Unable to start backup agent process " + r);
17227                return false;
17228            }
17229
17230            // If the app is a regular app (uid >= 10000) and not the system server or phone
17231            // process, etc, then mark it as being in full backup so that certain calls to the
17232            // process can be blocked. This is not reset to false anywhere because we kill the
17233            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17234            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17235                proc.inFullBackup = true;
17236            }
17237            r.app = proc;
17238            mBackupTarget = r;
17239            mBackupAppName = app.packageName;
17240
17241            // Try not to kill the process during backup
17242            updateOomAdjLocked(proc);
17243
17244            // If the process is already attached, schedule the creation of the backup agent now.
17245            // If it is not yet live, this will be done when it attaches to the framework.
17246            if (proc.thread != null) {
17247                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17248                try {
17249                    proc.thread.scheduleCreateBackupAgent(app,
17250                            compatibilityInfoForPackageLocked(app), backupMode);
17251                } catch (RemoteException e) {
17252                    // Will time out on the backup manager side
17253                }
17254            } else {
17255                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17256            }
17257            // Invariants: at this point, the target app process exists and the application
17258            // is either already running or in the process of coming up.  mBackupTarget and
17259            // mBackupAppName describe the app, so that when it binds back to the AM we
17260            // know that it's scheduled for a backup-agent operation.
17261        }
17262
17263        return true;
17264    }
17265
17266    @Override
17267    public void clearPendingBackup() {
17268        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17269        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17270
17271        synchronized (this) {
17272            mBackupTarget = null;
17273            mBackupAppName = null;
17274        }
17275    }
17276
17277    // A backup agent has just come up
17278    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17279        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17280                + " = " + agent);
17281
17282        synchronized(this) {
17283            if (!agentPackageName.equals(mBackupAppName)) {
17284                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17285                return;
17286            }
17287        }
17288
17289        long oldIdent = Binder.clearCallingIdentity();
17290        try {
17291            IBackupManager bm = IBackupManager.Stub.asInterface(
17292                    ServiceManager.getService(Context.BACKUP_SERVICE));
17293            bm.agentConnected(agentPackageName, agent);
17294        } catch (RemoteException e) {
17295            // can't happen; the backup manager service is local
17296        } catch (Exception e) {
17297            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17298            e.printStackTrace();
17299        } finally {
17300            Binder.restoreCallingIdentity(oldIdent);
17301        }
17302    }
17303
17304    // done with this agent
17305    public void unbindBackupAgent(ApplicationInfo appInfo) {
17306        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17307        if (appInfo == null) {
17308            Slog.w(TAG, "unbind backup agent for null app");
17309            return;
17310        }
17311
17312        synchronized(this) {
17313            try {
17314                if (mBackupAppName == null) {
17315                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17316                    return;
17317                }
17318
17319                if (!mBackupAppName.equals(appInfo.packageName)) {
17320                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17321                    return;
17322                }
17323
17324                // Not backing this app up any more; reset its OOM adjustment
17325                final ProcessRecord proc = mBackupTarget.app;
17326                updateOomAdjLocked(proc);
17327
17328                // If the app crashed during backup, 'thread' will be null here
17329                if (proc.thread != null) {
17330                    try {
17331                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17332                                compatibilityInfoForPackageLocked(appInfo));
17333                    } catch (Exception e) {
17334                        Slog.e(TAG, "Exception when unbinding backup agent:");
17335                        e.printStackTrace();
17336                    }
17337                }
17338            } finally {
17339                mBackupTarget = null;
17340                mBackupAppName = null;
17341            }
17342        }
17343    }
17344    // =========================================================
17345    // BROADCASTS
17346    // =========================================================
17347
17348    boolean isPendingBroadcastProcessLocked(int pid) {
17349        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17350                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17351    }
17352
17353    void skipPendingBroadcastLocked(int pid) {
17354            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17355            for (BroadcastQueue queue : mBroadcastQueues) {
17356                queue.skipPendingBroadcastLocked(pid);
17357            }
17358    }
17359
17360    // The app just attached; send any pending broadcasts that it should receive
17361    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17362        boolean didSomething = false;
17363        for (BroadcastQueue queue : mBroadcastQueues) {
17364            didSomething |= queue.sendPendingBroadcastsLocked(app);
17365        }
17366        return didSomething;
17367    }
17368
17369    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17370            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17371        enforceNotIsolatedCaller("registerReceiver");
17372        ArrayList<Intent> stickyIntents = null;
17373        ProcessRecord callerApp = null;
17374        int callingUid;
17375        int callingPid;
17376        synchronized(this) {
17377            if (caller != null) {
17378                callerApp = getRecordForAppLocked(caller);
17379                if (callerApp == null) {
17380                    throw new SecurityException(
17381                            "Unable to find app for caller " + caller
17382                            + " (pid=" + Binder.getCallingPid()
17383                            + ") when registering receiver " + receiver);
17384                }
17385                if (callerApp.info.uid != Process.SYSTEM_UID &&
17386                        !callerApp.pkgList.containsKey(callerPackage) &&
17387                        !"android".equals(callerPackage)) {
17388                    throw new SecurityException("Given caller package " + callerPackage
17389                            + " is not running in process " + callerApp);
17390                }
17391                callingUid = callerApp.info.uid;
17392                callingPid = callerApp.pid;
17393            } else {
17394                callerPackage = null;
17395                callingUid = Binder.getCallingUid();
17396                callingPid = Binder.getCallingPid();
17397            }
17398
17399            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17400                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17401
17402            Iterator<String> actions = filter.actionsIterator();
17403            if (actions == null) {
17404                ArrayList<String> noAction = new ArrayList<String>(1);
17405                noAction.add(null);
17406                actions = noAction.iterator();
17407            }
17408
17409            // Collect stickies of users
17410            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17411            while (actions.hasNext()) {
17412                String action = actions.next();
17413                for (int id : userIds) {
17414                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17415                    if (stickies != null) {
17416                        ArrayList<Intent> intents = stickies.get(action);
17417                        if (intents != null) {
17418                            if (stickyIntents == null) {
17419                                stickyIntents = new ArrayList<Intent>();
17420                            }
17421                            stickyIntents.addAll(intents);
17422                        }
17423                    }
17424                }
17425            }
17426        }
17427
17428        ArrayList<Intent> allSticky = null;
17429        if (stickyIntents != null) {
17430            final ContentResolver resolver = mContext.getContentResolver();
17431            // Look for any matching sticky broadcasts...
17432            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17433                Intent intent = stickyIntents.get(i);
17434                // If intent has scheme "content", it will need to acccess
17435                // provider that needs to lock mProviderMap in ActivityThread
17436                // and also it may need to wait application response, so we
17437                // cannot lock ActivityManagerService here.
17438                if (filter.match(resolver, intent, true, TAG) >= 0) {
17439                    if (allSticky == null) {
17440                        allSticky = new ArrayList<Intent>();
17441                    }
17442                    allSticky.add(intent);
17443                }
17444            }
17445        }
17446
17447        // The first sticky in the list is returned directly back to the client.
17448        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17449        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17450        if (receiver == null) {
17451            return sticky;
17452        }
17453
17454        synchronized (this) {
17455            if (callerApp != null && (callerApp.thread == null
17456                    || callerApp.thread.asBinder() != caller.asBinder())) {
17457                // Original caller already died
17458                return null;
17459            }
17460            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17461            if (rl == null) {
17462                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17463                        userId, receiver);
17464                if (rl.app != null) {
17465                    rl.app.receivers.add(rl);
17466                } else {
17467                    try {
17468                        receiver.asBinder().linkToDeath(rl, 0);
17469                    } catch (RemoteException e) {
17470                        return sticky;
17471                    }
17472                    rl.linkedToDeath = true;
17473                }
17474                mRegisteredReceivers.put(receiver.asBinder(), rl);
17475            } else if (rl.uid != callingUid) {
17476                throw new IllegalArgumentException(
17477                        "Receiver requested to register for uid " + callingUid
17478                        + " was previously registered for uid " + rl.uid);
17479            } else if (rl.pid != callingPid) {
17480                throw new IllegalArgumentException(
17481                        "Receiver requested to register for pid " + callingPid
17482                        + " was previously registered for pid " + rl.pid);
17483            } else if (rl.userId != userId) {
17484                throw new IllegalArgumentException(
17485                        "Receiver requested to register for user " + userId
17486                        + " was previously registered for user " + rl.userId);
17487            }
17488            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17489                    permission, callingUid, userId);
17490            rl.add(bf);
17491            if (!bf.debugCheck()) {
17492                Slog.w(TAG, "==> For Dynamic broadcast");
17493            }
17494            mReceiverResolver.addFilter(bf);
17495
17496            // Enqueue broadcasts for all existing stickies that match
17497            // this filter.
17498            if (allSticky != null) {
17499                ArrayList receivers = new ArrayList();
17500                receivers.add(bf);
17501
17502                final int stickyCount = allSticky.size();
17503                for (int i = 0; i < stickyCount; i++) {
17504                    Intent intent = allSticky.get(i);
17505                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17506                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17507                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17508                            null, 0, null, null, false, true, true, -1);
17509                    queue.enqueueParallelBroadcastLocked(r);
17510                    queue.scheduleBroadcastsLocked();
17511                }
17512            }
17513
17514            return sticky;
17515        }
17516    }
17517
17518    public void unregisterReceiver(IIntentReceiver receiver) {
17519        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17520
17521        final long origId = Binder.clearCallingIdentity();
17522        try {
17523            boolean doTrim = false;
17524
17525            synchronized(this) {
17526                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17527                if (rl != null) {
17528                    final BroadcastRecord r = rl.curBroadcast;
17529                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17530                        final boolean doNext = r.queue.finishReceiverLocked(
17531                                r, r.resultCode, r.resultData, r.resultExtras,
17532                                r.resultAbort, false);
17533                        if (doNext) {
17534                            doTrim = true;
17535                            r.queue.processNextBroadcast(false);
17536                        }
17537                    }
17538
17539                    if (rl.app != null) {
17540                        rl.app.receivers.remove(rl);
17541                    }
17542                    removeReceiverLocked(rl);
17543                    if (rl.linkedToDeath) {
17544                        rl.linkedToDeath = false;
17545                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17546                    }
17547                }
17548            }
17549
17550            // If we actually concluded any broadcasts, we might now be able
17551            // to trim the recipients' apps from our working set
17552            if (doTrim) {
17553                trimApplications();
17554                return;
17555            }
17556
17557        } finally {
17558            Binder.restoreCallingIdentity(origId);
17559        }
17560    }
17561
17562    void removeReceiverLocked(ReceiverList rl) {
17563        mRegisteredReceivers.remove(rl.receiver.asBinder());
17564        for (int i = rl.size() - 1; i >= 0; i--) {
17565            mReceiverResolver.removeFilter(rl.get(i));
17566        }
17567    }
17568
17569    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17570        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17571            ProcessRecord r = mLruProcesses.get(i);
17572            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17573                try {
17574                    r.thread.dispatchPackageBroadcast(cmd, packages);
17575                } catch (RemoteException ex) {
17576                }
17577            }
17578        }
17579    }
17580
17581    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17582            int callingUid, int[] users) {
17583        // TODO: come back and remove this assumption to triage all broadcasts
17584        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17585
17586        List<ResolveInfo> receivers = null;
17587        try {
17588            HashSet<ComponentName> singleUserReceivers = null;
17589            boolean scannedFirstReceivers = false;
17590            for (int user : users) {
17591                // Skip users that have Shell restrictions, with exception of always permitted
17592                // Shell broadcasts
17593                if (callingUid == Process.SHELL_UID
17594                        && mUserController.hasUserRestriction(
17595                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17596                        && !isPermittedShellBroadcast(intent)) {
17597                    continue;
17598                }
17599                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17600                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17601                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17602                    // If this is not the system user, we need to check for
17603                    // any receivers that should be filtered out.
17604                    for (int i=0; i<newReceivers.size(); i++) {
17605                        ResolveInfo ri = newReceivers.get(i);
17606                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17607                            newReceivers.remove(i);
17608                            i--;
17609                        }
17610                    }
17611                }
17612                if (newReceivers != null && newReceivers.size() == 0) {
17613                    newReceivers = null;
17614                }
17615                if (receivers == null) {
17616                    receivers = newReceivers;
17617                } else if (newReceivers != null) {
17618                    // We need to concatenate the additional receivers
17619                    // found with what we have do far.  This would be easy,
17620                    // but we also need to de-dup any receivers that are
17621                    // singleUser.
17622                    if (!scannedFirstReceivers) {
17623                        // Collect any single user receivers we had already retrieved.
17624                        scannedFirstReceivers = true;
17625                        for (int i=0; i<receivers.size(); i++) {
17626                            ResolveInfo ri = receivers.get(i);
17627                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17628                                ComponentName cn = new ComponentName(
17629                                        ri.activityInfo.packageName, ri.activityInfo.name);
17630                                if (singleUserReceivers == null) {
17631                                    singleUserReceivers = new HashSet<ComponentName>();
17632                                }
17633                                singleUserReceivers.add(cn);
17634                            }
17635                        }
17636                    }
17637                    // Add the new results to the existing results, tracking
17638                    // and de-dupping single user receivers.
17639                    for (int i=0; i<newReceivers.size(); i++) {
17640                        ResolveInfo ri = newReceivers.get(i);
17641                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17642                            ComponentName cn = new ComponentName(
17643                                    ri.activityInfo.packageName, ri.activityInfo.name);
17644                            if (singleUserReceivers == null) {
17645                                singleUserReceivers = new HashSet<ComponentName>();
17646                            }
17647                            if (!singleUserReceivers.contains(cn)) {
17648                                singleUserReceivers.add(cn);
17649                                receivers.add(ri);
17650                            }
17651                        } else {
17652                            receivers.add(ri);
17653                        }
17654                    }
17655                }
17656            }
17657        } catch (RemoteException ex) {
17658            // pm is in same process, this will never happen.
17659        }
17660        return receivers;
17661    }
17662
17663    private boolean isPermittedShellBroadcast(Intent intent) {
17664        // remote bugreport should always be allowed to be taken
17665        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17666    }
17667
17668    final int broadcastIntentLocked(ProcessRecord callerApp,
17669            String callerPackage, Intent intent, String resolvedType,
17670            IIntentReceiver resultTo, int resultCode, String resultData,
17671            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17672            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17673        intent = new Intent(intent);
17674
17675        // By default broadcasts do not go to stopped apps.
17676        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17677
17678        // If we have not finished booting, don't allow this to launch new processes.
17679        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17680            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17681        }
17682
17683        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17684                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17685                + " ordered=" + ordered + " userid=" + userId);
17686        if ((resultTo != null) && !ordered) {
17687            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17688        }
17689
17690        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17691                ALLOW_NON_FULL, "broadcast", callerPackage);
17692
17693        // Make sure that the user who is receiving this broadcast is running.
17694        // If not, we will just skip it. Make an exception for shutdown broadcasts
17695        // and upgrade steps.
17696
17697        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17698            if ((callingUid != Process.SYSTEM_UID
17699                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17700                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17701                Slog.w(TAG, "Skipping broadcast of " + intent
17702                        + ": user " + userId + " is stopped");
17703                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17704            }
17705        }
17706
17707        BroadcastOptions brOptions = null;
17708        if (bOptions != null) {
17709            brOptions = new BroadcastOptions(bOptions);
17710            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17711                // See if the caller is allowed to do this.  Note we are checking against
17712                // the actual real caller (not whoever provided the operation as say a
17713                // PendingIntent), because that who is actually supplied the arguments.
17714                if (checkComponentPermission(
17715                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17716                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17717                        != PackageManager.PERMISSION_GRANTED) {
17718                    String msg = "Permission Denial: " + intent.getAction()
17719                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17720                            + ", uid=" + callingUid + ")"
17721                            + " requires "
17722                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17723                    Slog.w(TAG, msg);
17724                    throw new SecurityException(msg);
17725                }
17726            }
17727        }
17728
17729        // Verify that protected broadcasts are only being sent by system code,
17730        // and that system code is only sending protected broadcasts.
17731        final String action = intent.getAction();
17732        final boolean isProtectedBroadcast;
17733        try {
17734            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17735        } catch (RemoteException e) {
17736            Slog.w(TAG, "Remote exception", e);
17737            return ActivityManager.BROADCAST_SUCCESS;
17738        }
17739
17740        final boolean isCallerSystem;
17741        switch (UserHandle.getAppId(callingUid)) {
17742            case Process.ROOT_UID:
17743            case Process.SYSTEM_UID:
17744            case Process.PHONE_UID:
17745            case Process.BLUETOOTH_UID:
17746            case Process.NFC_UID:
17747                isCallerSystem = true;
17748                break;
17749            default:
17750                isCallerSystem = (callerApp != null) && callerApp.persistent;
17751                break;
17752        }
17753
17754        if (isCallerSystem) {
17755            if (isProtectedBroadcast
17756                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17757                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17758                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17759                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17760                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17761                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17762                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17763                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17764                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17765                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17766                // Broadcast is either protected, or it's a public action that
17767                // we've relaxed, so it's fine for system internals to send.
17768            } else {
17769                // The vast majority of broadcasts sent from system internals
17770                // should be protected to avoid security holes, so yell loudly
17771                // to ensure we examine these cases.
17772                if (callerApp != null) {
17773                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17774                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17775                            new Throwable());
17776                } else {
17777                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17778                            + " from system uid " + UserHandle.formatUid(callingUid)
17779                            + " pkg " + callerPackage,
17780                            new Throwable());
17781                }
17782            }
17783
17784        } else {
17785            if (isProtectedBroadcast) {
17786                String msg = "Permission Denial: not allowed to send broadcast "
17787                        + action + " from pid="
17788                        + callingPid + ", uid=" + callingUid;
17789                Slog.w(TAG, msg);
17790                throw new SecurityException(msg);
17791
17792            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17793                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17794                // Special case for compatibility: we don't want apps to send this,
17795                // but historically it has not been protected and apps may be using it
17796                // to poke their own app widget.  So, instead of making it protected,
17797                // just limit it to the caller.
17798                if (callerPackage == null) {
17799                    String msg = "Permission Denial: not allowed to send broadcast "
17800                            + action + " from unknown caller.";
17801                    Slog.w(TAG, msg);
17802                    throw new SecurityException(msg);
17803                } else if (intent.getComponent() != null) {
17804                    // They are good enough to send to an explicit component...  verify
17805                    // it is being sent to the calling app.
17806                    if (!intent.getComponent().getPackageName().equals(
17807                            callerPackage)) {
17808                        String msg = "Permission Denial: not allowed to send broadcast "
17809                                + action + " to "
17810                                + intent.getComponent().getPackageName() + " from "
17811                                + callerPackage;
17812                        Slog.w(TAG, msg);
17813                        throw new SecurityException(msg);
17814                    }
17815                } else {
17816                    // Limit broadcast to their own package.
17817                    intent.setPackage(callerPackage);
17818                }
17819            }
17820        }
17821
17822        if (action != null) {
17823            switch (action) {
17824                case Intent.ACTION_UID_REMOVED:
17825                case Intent.ACTION_PACKAGE_REMOVED:
17826                case Intent.ACTION_PACKAGE_CHANGED:
17827                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17828                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17829                case Intent.ACTION_PACKAGES_SUSPENDED:
17830                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17831                    // Handle special intents: if this broadcast is from the package
17832                    // manager about a package being removed, we need to remove all of
17833                    // its activities from the history stack.
17834                    if (checkComponentPermission(
17835                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17836                            callingPid, callingUid, -1, true)
17837                            != PackageManager.PERMISSION_GRANTED) {
17838                        String msg = "Permission Denial: " + intent.getAction()
17839                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17840                                + ", uid=" + callingUid + ")"
17841                                + " requires "
17842                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17843                        Slog.w(TAG, msg);
17844                        throw new SecurityException(msg);
17845                    }
17846                    switch (action) {
17847                        case Intent.ACTION_UID_REMOVED:
17848                            final Bundle intentExtras = intent.getExtras();
17849                            final int uid = intentExtras != null
17850                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17851                            if (uid >= 0) {
17852                                mBatteryStatsService.removeUid(uid);
17853                                mAppOpsService.uidRemoved(uid);
17854                            }
17855                            break;
17856                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17857                            // If resources are unavailable just force stop all those packages
17858                            // and flush the attribute cache as well.
17859                            String list[] =
17860                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17861                            if (list != null && list.length > 0) {
17862                                for (int i = 0; i < list.length; i++) {
17863                                    forceStopPackageLocked(list[i], -1, false, true, true,
17864                                            false, false, userId, "storage unmount");
17865                                }
17866                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17867                                sendPackageBroadcastLocked(
17868                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17869                                        userId);
17870                            }
17871                            break;
17872                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17873                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17874                            break;
17875                        case Intent.ACTION_PACKAGE_REMOVED:
17876                        case Intent.ACTION_PACKAGE_CHANGED:
17877                            Uri data = intent.getData();
17878                            String ssp;
17879                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17880                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17881                                final boolean replacing =
17882                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17883                                final boolean killProcess =
17884                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17885                                final boolean fullUninstall = removed && !replacing;
17886                                if (removed) {
17887                                    if (killProcess) {
17888                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17889                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17890                                                false, true, true, false, fullUninstall, userId,
17891                                                removed ? "pkg removed" : "pkg changed");
17892                                    }
17893                                    final int cmd = killProcess
17894                                            ? IApplicationThread.PACKAGE_REMOVED
17895                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17896                                    sendPackageBroadcastLocked(cmd,
17897                                            new String[] {ssp}, userId);
17898                                    if (fullUninstall) {
17899                                        mAppOpsService.packageRemoved(
17900                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17901
17902                                        // Remove all permissions granted from/to this package
17903                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17904
17905                                        removeTasksByPackageNameLocked(ssp, userId);
17906
17907                                        // Hide the "unsupported display" dialog if necessary.
17908                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17909                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17910                                            mUnsupportedDisplaySizeDialog.dismiss();
17911                                            mUnsupportedDisplaySizeDialog = null;
17912                                        }
17913                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17914                                        mBatteryStatsService.notePackageUninstalled(ssp);
17915                                    }
17916                                } else {
17917                                    if (killProcess) {
17918                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17919                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17920                                                userId, ProcessList.INVALID_ADJ,
17921                                                false, true, true, false, "change " + ssp);
17922                                    }
17923                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17924                                            intent.getStringArrayExtra(
17925                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17926                                }
17927                            }
17928                            break;
17929                        case Intent.ACTION_PACKAGES_SUSPENDED:
17930                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17931                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17932                                    intent.getAction());
17933                            final String[] packageNames = intent.getStringArrayExtra(
17934                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17935                            final int userHandle = intent.getIntExtra(
17936                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17937
17938                            synchronized(ActivityManagerService.this) {
17939                                mRecentTasks.onPackagesSuspendedChanged(
17940                                        packageNames, suspended, userHandle);
17941                            }
17942                            break;
17943                    }
17944                    break;
17945                case Intent.ACTION_PACKAGE_REPLACED:
17946                {
17947                    final Uri data = intent.getData();
17948                    final String ssp;
17949                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17950                        final ApplicationInfo aInfo =
17951                                getPackageManagerInternalLocked().getApplicationInfo(
17952                                        ssp,
17953                                        userId);
17954                        if (aInfo == null) {
17955                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17956                                    + " ssp=" + ssp + " data=" + data);
17957                            return ActivityManager.BROADCAST_SUCCESS;
17958                        }
17959                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17960                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17961                                new String[] {ssp}, userId);
17962                    }
17963                    break;
17964                }
17965                case Intent.ACTION_PACKAGE_ADDED:
17966                {
17967                    // Special case for adding a package: by default turn on compatibility mode.
17968                    Uri data = intent.getData();
17969                    String ssp;
17970                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17971                        final boolean replacing =
17972                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17973                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17974
17975                        try {
17976                            ApplicationInfo ai = AppGlobals.getPackageManager().
17977                                    getApplicationInfo(ssp, 0, 0);
17978                            mBatteryStatsService.notePackageInstalled(ssp,
17979                                    ai != null ? ai.versionCode : 0);
17980                        } catch (RemoteException e) {
17981                        }
17982                    }
17983                    break;
17984                }
17985                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17986                {
17987                    Uri data = intent.getData();
17988                    String ssp;
17989                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17990                        // Hide the "unsupported display" dialog if necessary.
17991                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17992                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17993                            mUnsupportedDisplaySizeDialog.dismiss();
17994                            mUnsupportedDisplaySizeDialog = null;
17995                        }
17996                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17997                    }
17998                    break;
17999                }
18000                case Intent.ACTION_TIMEZONE_CHANGED:
18001                    // If this is the time zone changed action, queue up a message that will reset
18002                    // the timezone of all currently running processes. This message will get
18003                    // queued up before the broadcast happens.
18004                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18005                    break;
18006                case Intent.ACTION_TIME_CHANGED:
18007                    // If the user set the time, let all running processes know.
18008                    final int is24Hour =
18009                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18010                                    : 0;
18011                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18012                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18013                    synchronized (stats) {
18014                        stats.noteCurrentTimeChangedLocked();
18015                    }
18016                    break;
18017                case Intent.ACTION_CLEAR_DNS_CACHE:
18018                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18019                    break;
18020                case Proxy.PROXY_CHANGE_ACTION:
18021                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18022                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18023                    break;
18024                case android.hardware.Camera.ACTION_NEW_PICTURE:
18025                case android.hardware.Camera.ACTION_NEW_VIDEO:
18026                    // These broadcasts are no longer allowed by the system, since they can
18027                    // cause significant thrashing at a crictical point (using the camera).
18028                    // Apps should use JobScehduler to monitor for media provider changes.
18029                    Slog.w(TAG, action + " no longer allowed; dropping from "
18030                            + UserHandle.formatUid(callingUid));
18031                    if (resultTo != null) {
18032                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18033                        try {
18034                            queue.performReceiveLocked(callerApp, resultTo, intent,
18035                                    Activity.RESULT_CANCELED, null, null,
18036                                    false, false, userId);
18037                        } catch (RemoteException e) {
18038                            Slog.w(TAG, "Failure ["
18039                                    + queue.mQueueName + "] sending broadcast result of "
18040                                    + intent, e);
18041
18042                        }
18043                    }
18044                    // Lie; we don't want to crash the app.
18045                    return ActivityManager.BROADCAST_SUCCESS;
18046            }
18047        }
18048
18049        // Add to the sticky list if requested.
18050        if (sticky) {
18051            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18052                    callingPid, callingUid)
18053                    != PackageManager.PERMISSION_GRANTED) {
18054                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18055                        + callingPid + ", uid=" + callingUid
18056                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18057                Slog.w(TAG, msg);
18058                throw new SecurityException(msg);
18059            }
18060            if (requiredPermissions != null && requiredPermissions.length > 0) {
18061                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18062                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18063                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18064            }
18065            if (intent.getComponent() != null) {
18066                throw new SecurityException(
18067                        "Sticky broadcasts can't target a specific component");
18068            }
18069            // We use userId directly here, since the "all" target is maintained
18070            // as a separate set of sticky broadcasts.
18071            if (userId != UserHandle.USER_ALL) {
18072                // But first, if this is not a broadcast to all users, then
18073                // make sure it doesn't conflict with an existing broadcast to
18074                // all users.
18075                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18076                        UserHandle.USER_ALL);
18077                if (stickies != null) {
18078                    ArrayList<Intent> list = stickies.get(intent.getAction());
18079                    if (list != null) {
18080                        int N = list.size();
18081                        int i;
18082                        for (i=0; i<N; i++) {
18083                            if (intent.filterEquals(list.get(i))) {
18084                                throw new IllegalArgumentException(
18085                                        "Sticky broadcast " + intent + " for user "
18086                                        + userId + " conflicts with existing global broadcast");
18087                            }
18088                        }
18089                    }
18090                }
18091            }
18092            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18093            if (stickies == null) {
18094                stickies = new ArrayMap<>();
18095                mStickyBroadcasts.put(userId, stickies);
18096            }
18097            ArrayList<Intent> list = stickies.get(intent.getAction());
18098            if (list == null) {
18099                list = new ArrayList<>();
18100                stickies.put(intent.getAction(), list);
18101            }
18102            final int stickiesCount = list.size();
18103            int i;
18104            for (i = 0; i < stickiesCount; i++) {
18105                if (intent.filterEquals(list.get(i))) {
18106                    // This sticky already exists, replace it.
18107                    list.set(i, new Intent(intent));
18108                    break;
18109                }
18110            }
18111            if (i >= stickiesCount) {
18112                list.add(new Intent(intent));
18113            }
18114        }
18115
18116        int[] users;
18117        if (userId == UserHandle.USER_ALL) {
18118            // Caller wants broadcast to go to all started users.
18119            users = mUserController.getStartedUserArrayLocked();
18120        } else {
18121            // Caller wants broadcast to go to one specific user.
18122            users = new int[] {userId};
18123        }
18124
18125        // Figure out who all will receive this broadcast.
18126        List receivers = null;
18127        List<BroadcastFilter> registeredReceivers = null;
18128        // Need to resolve the intent to interested receivers...
18129        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18130                 == 0) {
18131            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18132        }
18133        if (intent.getComponent() == null) {
18134            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18135                // Query one target user at a time, excluding shell-restricted users
18136                for (int i = 0; i < users.length; i++) {
18137                    if (mUserController.hasUserRestriction(
18138                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18139                        continue;
18140                    }
18141                    List<BroadcastFilter> registeredReceiversForUser =
18142                            mReceiverResolver.queryIntent(intent,
18143                                    resolvedType, false, users[i]);
18144                    if (registeredReceivers == null) {
18145                        registeredReceivers = registeredReceiversForUser;
18146                    } else if (registeredReceiversForUser != null) {
18147                        registeredReceivers.addAll(registeredReceiversForUser);
18148                    }
18149                }
18150            } else {
18151                registeredReceivers = mReceiverResolver.queryIntent(intent,
18152                        resolvedType, false, userId);
18153            }
18154        }
18155
18156        final boolean replacePending =
18157                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18158
18159        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18160                + " replacePending=" + replacePending);
18161
18162        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18163        if (!ordered && NR > 0) {
18164            // If we are not serializing this broadcast, then send the
18165            // registered receivers separately so they don't wait for the
18166            // components to be launched.
18167            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18168            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18169                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18170                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18171                    resultExtras, ordered, sticky, false, userId);
18172            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18173            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18174            if (!replaced) {
18175                queue.enqueueParallelBroadcastLocked(r);
18176                queue.scheduleBroadcastsLocked();
18177            }
18178            registeredReceivers = null;
18179            NR = 0;
18180        }
18181
18182        // Merge into one list.
18183        int ir = 0;
18184        if (receivers != null) {
18185            // A special case for PACKAGE_ADDED: do not allow the package
18186            // being added to see this broadcast.  This prevents them from
18187            // using this as a back door to get run as soon as they are
18188            // installed.  Maybe in the future we want to have a special install
18189            // broadcast or such for apps, but we'd like to deliberately make
18190            // this decision.
18191            String skipPackages[] = null;
18192            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18193                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18194                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18195                Uri data = intent.getData();
18196                if (data != null) {
18197                    String pkgName = data.getSchemeSpecificPart();
18198                    if (pkgName != null) {
18199                        skipPackages = new String[] { pkgName };
18200                    }
18201                }
18202            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18203                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18204            }
18205            if (skipPackages != null && (skipPackages.length > 0)) {
18206                for (String skipPackage : skipPackages) {
18207                    if (skipPackage != null) {
18208                        int NT = receivers.size();
18209                        for (int it=0; it<NT; it++) {
18210                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18211                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18212                                receivers.remove(it);
18213                                it--;
18214                                NT--;
18215                            }
18216                        }
18217                    }
18218                }
18219            }
18220
18221            int NT = receivers != null ? receivers.size() : 0;
18222            int it = 0;
18223            ResolveInfo curt = null;
18224            BroadcastFilter curr = null;
18225            while (it < NT && ir < NR) {
18226                if (curt == null) {
18227                    curt = (ResolveInfo)receivers.get(it);
18228                }
18229                if (curr == null) {
18230                    curr = registeredReceivers.get(ir);
18231                }
18232                if (curr.getPriority() >= curt.priority) {
18233                    // Insert this broadcast record into the final list.
18234                    receivers.add(it, curr);
18235                    ir++;
18236                    curr = null;
18237                    it++;
18238                    NT++;
18239                } else {
18240                    // Skip to the next ResolveInfo in the final list.
18241                    it++;
18242                    curt = null;
18243                }
18244            }
18245        }
18246        while (ir < NR) {
18247            if (receivers == null) {
18248                receivers = new ArrayList();
18249            }
18250            receivers.add(registeredReceivers.get(ir));
18251            ir++;
18252        }
18253
18254        if ((receivers != null && receivers.size() > 0)
18255                || resultTo != null) {
18256            BroadcastQueue queue = broadcastQueueForIntent(intent);
18257            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18258                    callerPackage, callingPid, callingUid, resolvedType,
18259                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18260                    resultData, resultExtras, ordered, sticky, false, userId);
18261
18262            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18263                    + ": prev had " + queue.mOrderedBroadcasts.size());
18264            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18265                    "Enqueueing broadcast " + r.intent.getAction());
18266
18267            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18268            if (!replaced) {
18269                queue.enqueueOrderedBroadcastLocked(r);
18270                queue.scheduleBroadcastsLocked();
18271            }
18272        } else {
18273            // There was nobody interested in the broadcast, but we still want to record
18274            // that it happened.
18275            if (intent.getComponent() == null && intent.getPackage() == null
18276                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18277                // This was an implicit broadcast... let's record it for posterity.
18278                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18279            }
18280        }
18281
18282        return ActivityManager.BROADCAST_SUCCESS;
18283    }
18284
18285    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18286            int skipCount, long dispatchTime) {
18287        final long now = SystemClock.elapsedRealtime();
18288        if (mCurBroadcastStats == null ||
18289                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18290            mLastBroadcastStats = mCurBroadcastStats;
18291            if (mLastBroadcastStats != null) {
18292                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18293                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18294            }
18295            mCurBroadcastStats = new BroadcastStats();
18296        }
18297        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18298    }
18299
18300    final Intent verifyBroadcastLocked(Intent intent) {
18301        // Refuse possible leaked file descriptors
18302        if (intent != null && intent.hasFileDescriptors() == true) {
18303            throw new IllegalArgumentException("File descriptors passed in Intent");
18304        }
18305
18306        int flags = intent.getFlags();
18307
18308        if (!mProcessesReady) {
18309            // if the caller really truly claims to know what they're doing, go
18310            // ahead and allow the broadcast without launching any receivers
18311            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18312                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18313            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18314                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18315                        + " before boot completion");
18316                throw new IllegalStateException("Cannot broadcast before boot completed");
18317            }
18318        }
18319
18320        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18321            throw new IllegalArgumentException(
18322                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18323        }
18324
18325        return intent;
18326    }
18327
18328    public final int broadcastIntent(IApplicationThread caller,
18329            Intent intent, String resolvedType, IIntentReceiver resultTo,
18330            int resultCode, String resultData, Bundle resultExtras,
18331            String[] requiredPermissions, int appOp, Bundle bOptions,
18332            boolean serialized, boolean sticky, int userId) {
18333        enforceNotIsolatedCaller("broadcastIntent");
18334        synchronized(this) {
18335            intent = verifyBroadcastLocked(intent);
18336
18337            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18338            final int callingPid = Binder.getCallingPid();
18339            final int callingUid = Binder.getCallingUid();
18340            final long origId = Binder.clearCallingIdentity();
18341            int res = broadcastIntentLocked(callerApp,
18342                    callerApp != null ? callerApp.info.packageName : null,
18343                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18344                    requiredPermissions, appOp, bOptions, serialized, sticky,
18345                    callingPid, callingUid, userId);
18346            Binder.restoreCallingIdentity(origId);
18347            return res;
18348        }
18349    }
18350
18351
18352    int broadcastIntentInPackage(String packageName, int uid,
18353            Intent intent, String resolvedType, IIntentReceiver resultTo,
18354            int resultCode, String resultData, Bundle resultExtras,
18355            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18356            int userId) {
18357        synchronized(this) {
18358            intent = verifyBroadcastLocked(intent);
18359
18360            final long origId = Binder.clearCallingIdentity();
18361            String[] requiredPermissions = requiredPermission == null ? null
18362                    : new String[] {requiredPermission};
18363            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18364                    resultTo, resultCode, resultData, resultExtras,
18365                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18366                    sticky, -1, uid, userId);
18367            Binder.restoreCallingIdentity(origId);
18368            return res;
18369        }
18370    }
18371
18372    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18373        // Refuse possible leaked file descriptors
18374        if (intent != null && intent.hasFileDescriptors() == true) {
18375            throw new IllegalArgumentException("File descriptors passed in Intent");
18376        }
18377
18378        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18379                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18380
18381        synchronized(this) {
18382            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18383                    != PackageManager.PERMISSION_GRANTED) {
18384                String msg = "Permission Denial: unbroadcastIntent() from pid="
18385                        + Binder.getCallingPid()
18386                        + ", uid=" + Binder.getCallingUid()
18387                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18388                Slog.w(TAG, msg);
18389                throw new SecurityException(msg);
18390            }
18391            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18392            if (stickies != null) {
18393                ArrayList<Intent> list = stickies.get(intent.getAction());
18394                if (list != null) {
18395                    int N = list.size();
18396                    int i;
18397                    for (i=0; i<N; i++) {
18398                        if (intent.filterEquals(list.get(i))) {
18399                            list.remove(i);
18400                            break;
18401                        }
18402                    }
18403                    if (list.size() <= 0) {
18404                        stickies.remove(intent.getAction());
18405                    }
18406                }
18407                if (stickies.size() <= 0) {
18408                    mStickyBroadcasts.remove(userId);
18409                }
18410            }
18411        }
18412    }
18413
18414    void backgroundServicesFinishedLocked(int userId) {
18415        for (BroadcastQueue queue : mBroadcastQueues) {
18416            queue.backgroundServicesFinishedLocked(userId);
18417        }
18418    }
18419
18420    public void finishReceiver(IBinder who, int resultCode, String resultData,
18421            Bundle resultExtras, boolean resultAbort, int flags) {
18422        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18423
18424        // Refuse possible leaked file descriptors
18425        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18426            throw new IllegalArgumentException("File descriptors passed in Bundle");
18427        }
18428
18429        final long origId = Binder.clearCallingIdentity();
18430        try {
18431            boolean doNext = false;
18432            BroadcastRecord r;
18433
18434            synchronized(this) {
18435                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18436                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18437                r = queue.getMatchingOrderedReceiver(who);
18438                if (r != null) {
18439                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18440                        resultData, resultExtras, resultAbort, true);
18441                }
18442            }
18443
18444            if (doNext) {
18445                r.queue.processNextBroadcast(false);
18446            }
18447            trimApplications();
18448        } finally {
18449            Binder.restoreCallingIdentity(origId);
18450        }
18451    }
18452
18453    // =========================================================
18454    // INSTRUMENTATION
18455    // =========================================================
18456
18457    public boolean startInstrumentation(ComponentName className,
18458            String profileFile, int flags, Bundle arguments,
18459            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18460            int userId, String abiOverride) {
18461        enforceNotIsolatedCaller("startInstrumentation");
18462        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18463                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18464        // Refuse possible leaked file descriptors
18465        if (arguments != null && arguments.hasFileDescriptors()) {
18466            throw new IllegalArgumentException("File descriptors passed in Bundle");
18467        }
18468
18469        synchronized(this) {
18470            InstrumentationInfo ii = null;
18471            ApplicationInfo ai = null;
18472            try {
18473                ii = mContext.getPackageManager().getInstrumentationInfo(
18474                    className, STOCK_PM_FLAGS);
18475                ai = AppGlobals.getPackageManager().getApplicationInfo(
18476                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18477            } catch (PackageManager.NameNotFoundException e) {
18478            } catch (RemoteException e) {
18479            }
18480            if (ii == null) {
18481                reportStartInstrumentationFailureLocked(watcher, className,
18482                        "Unable to find instrumentation info for: " + className);
18483                return false;
18484            }
18485            if (ai == null) {
18486                reportStartInstrumentationFailureLocked(watcher, className,
18487                        "Unable to find instrumentation target package: " + ii.targetPackage);
18488                return false;
18489            }
18490            if (!ai.hasCode()) {
18491                reportStartInstrumentationFailureLocked(watcher, className,
18492                        "Instrumentation target has no code: " + ii.targetPackage);
18493                return false;
18494            }
18495
18496            int match = mContext.getPackageManager().checkSignatures(
18497                    ii.targetPackage, ii.packageName);
18498            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18499                String msg = "Permission Denial: starting instrumentation "
18500                        + className + " from pid="
18501                        + Binder.getCallingPid()
18502                        + ", uid=" + Binder.getCallingPid()
18503                        + " not allowed because package " + ii.packageName
18504                        + " does not have a signature matching the target "
18505                        + ii.targetPackage;
18506                reportStartInstrumentationFailureLocked(watcher, className, msg);
18507                throw new SecurityException(msg);
18508            }
18509
18510            final long origId = Binder.clearCallingIdentity();
18511            // Instrumentation can kill and relaunch even persistent processes
18512            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18513                    "start instr");
18514            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18515            app.instrumentationClass = className;
18516            app.instrumentationInfo = ai;
18517            app.instrumentationProfileFile = profileFile;
18518            app.instrumentationArguments = arguments;
18519            app.instrumentationWatcher = watcher;
18520            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18521            app.instrumentationResultClass = className;
18522            Binder.restoreCallingIdentity(origId);
18523        }
18524
18525        return true;
18526    }
18527
18528    /**
18529     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18530     * error to the logs, but if somebody is watching, send the report there too.  This enables
18531     * the "am" command to report errors with more information.
18532     *
18533     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18534     * @param cn The component name of the instrumentation.
18535     * @param report The error report.
18536     */
18537    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18538            ComponentName cn, String report) {
18539        Slog.w(TAG, report);
18540        if (watcher != null) {
18541            Bundle results = new Bundle();
18542            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18543            results.putString("Error", report);
18544            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18545        }
18546    }
18547
18548    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18549        if (app.instrumentationWatcher != null) {
18550            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18551                    app.instrumentationClass, resultCode, results);
18552        }
18553
18554        // Can't call out of the system process with a lock held, so post a message.
18555        if (app.instrumentationUiAutomationConnection != null) {
18556            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18557                    app.instrumentationUiAutomationConnection).sendToTarget();
18558        }
18559
18560        app.instrumentationWatcher = null;
18561        app.instrumentationUiAutomationConnection = null;
18562        app.instrumentationClass = null;
18563        app.instrumentationInfo = null;
18564        app.instrumentationProfileFile = null;
18565        app.instrumentationArguments = null;
18566
18567        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18568                "finished inst");
18569    }
18570
18571    public void finishInstrumentation(IApplicationThread target,
18572            int resultCode, Bundle results) {
18573        int userId = UserHandle.getCallingUserId();
18574        // Refuse possible leaked file descriptors
18575        if (results != null && results.hasFileDescriptors()) {
18576            throw new IllegalArgumentException("File descriptors passed in Intent");
18577        }
18578
18579        synchronized(this) {
18580            ProcessRecord app = getRecordForAppLocked(target);
18581            if (app == null) {
18582                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18583                return;
18584            }
18585            final long origId = Binder.clearCallingIdentity();
18586            finishInstrumentationLocked(app, resultCode, results);
18587            Binder.restoreCallingIdentity(origId);
18588        }
18589    }
18590
18591    // =========================================================
18592    // CONFIGURATION
18593    // =========================================================
18594
18595    public ConfigurationInfo getDeviceConfigurationInfo() {
18596        ConfigurationInfo config = new ConfigurationInfo();
18597        synchronized (this) {
18598            config.reqTouchScreen = mConfiguration.touchscreen;
18599            config.reqKeyboardType = mConfiguration.keyboard;
18600            config.reqNavigation = mConfiguration.navigation;
18601            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18602                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18603                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18604            }
18605            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18606                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18607                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18608            }
18609            config.reqGlEsVersion = GL_ES_VERSION;
18610        }
18611        return config;
18612    }
18613
18614    ActivityStack getFocusedStack() {
18615        return mStackSupervisor.getFocusedStack();
18616    }
18617
18618    @Override
18619    public int getFocusedStackId() throws RemoteException {
18620        ActivityStack focusedStack = getFocusedStack();
18621        if (focusedStack != null) {
18622            return focusedStack.getStackId();
18623        }
18624        return -1;
18625    }
18626
18627    public Configuration getConfiguration() {
18628        Configuration ci;
18629        synchronized(this) {
18630            ci = new Configuration(mConfiguration);
18631            ci.userSetLocale = false;
18632        }
18633        return ci;
18634    }
18635
18636    @Override
18637    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18638        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18639        synchronized (this) {
18640            mSuppressResizeConfigChanges = suppress;
18641        }
18642    }
18643
18644    @Override
18645    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18646        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18647        if (fromStackId == HOME_STACK_ID) {
18648            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18649        }
18650        synchronized (this) {
18651            final long origId = Binder.clearCallingIdentity();
18652            try {
18653                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18654            } finally {
18655                Binder.restoreCallingIdentity(origId);
18656            }
18657        }
18658    }
18659
18660    @Override
18661    public void updatePersistentConfiguration(Configuration values) {
18662        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18663                "updateConfiguration()");
18664        enforceWriteSettingsPermission("updateConfiguration()");
18665        if (values == null) {
18666            throw new NullPointerException("Configuration must not be null");
18667        }
18668
18669        int userId = UserHandle.getCallingUserId();
18670
18671        synchronized(this) {
18672            final long origId = Binder.clearCallingIdentity();
18673            updateConfigurationLocked(values, null, false, true, userId);
18674            Binder.restoreCallingIdentity(origId);
18675        }
18676    }
18677
18678    private void updateFontScaleIfNeeded() {
18679        final int currentUserId;
18680        synchronized(this) {
18681            currentUserId = mUserController.getCurrentUserIdLocked();
18682        }
18683        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18684                FONT_SCALE, 1.0f, currentUserId);
18685        if (mConfiguration.fontScale != scaleFactor) {
18686            final Configuration configuration = mWindowManager.computeNewConfiguration();
18687            configuration.fontScale = scaleFactor;
18688            updatePersistentConfiguration(configuration);
18689        }
18690    }
18691
18692    private void enforceWriteSettingsPermission(String func) {
18693        int uid = Binder.getCallingUid();
18694        if (uid == Process.ROOT_UID) {
18695            return;
18696        }
18697
18698        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18699                Settings.getPackageNameForUid(mContext, uid), false)) {
18700            return;
18701        }
18702
18703        String msg = "Permission Denial: " + func + " from pid="
18704                + Binder.getCallingPid()
18705                + ", uid=" + uid
18706                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18707        Slog.w(TAG, msg);
18708        throw new SecurityException(msg);
18709    }
18710
18711    public void updateConfiguration(Configuration values) {
18712        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18713                "updateConfiguration()");
18714
18715        synchronized(this) {
18716            if (values == null && mWindowManager != null) {
18717                // sentinel: fetch the current configuration from the window manager
18718                values = mWindowManager.computeNewConfiguration();
18719            }
18720
18721            if (mWindowManager != null) {
18722                mProcessList.applyDisplaySize(mWindowManager);
18723            }
18724
18725            final long origId = Binder.clearCallingIdentity();
18726            if (values != null) {
18727                Settings.System.clearConfiguration(values);
18728            }
18729            updateConfigurationLocked(values, null, false);
18730            Binder.restoreCallingIdentity(origId);
18731        }
18732    }
18733
18734    void updateUserConfigurationLocked() {
18735        Configuration configuration = new Configuration(mConfiguration);
18736        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18737                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18738        updateConfigurationLocked(configuration, null, false);
18739    }
18740
18741    boolean updateConfigurationLocked(Configuration values,
18742            ActivityRecord starting, boolean initLocale) {
18743        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18744        return updateConfigurationLocked(values, starting, initLocale, false,
18745                UserHandle.USER_NULL);
18746    }
18747
18748    // To cache the list of supported system locales
18749    private String[] mSupportedSystemLocales = null;
18750
18751    /**
18752     * Do either or both things: (1) change the current configuration, and (2)
18753     * make sure the given activity is running with the (now) current
18754     * configuration.  Returns true if the activity has been left running, or
18755     * false if <var>starting</var> is being destroyed to match the new
18756     * configuration.
18757     *
18758     * @param userId is only used when persistent parameter is set to true to persist configuration
18759     *               for that particular user
18760     */
18761    private boolean updateConfigurationLocked(Configuration values,
18762            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18763        int changes = 0;
18764
18765        if (mWindowManager != null) {
18766            mWindowManager.deferSurfaceLayout();
18767        }
18768        if (values != null) {
18769            Configuration newConfig = new Configuration(mConfiguration);
18770            changes = newConfig.updateFrom(values);
18771            if (changes != 0) {
18772                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18773                        "Updating configuration to: " + values);
18774
18775                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18776
18777                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18778                    final LocaleList locales = values.getLocales();
18779                    int bestLocaleIndex = 0;
18780                    if (locales.size() > 1) {
18781                        if (mSupportedSystemLocales == null) {
18782                            mSupportedSystemLocales =
18783                                    Resources.getSystem().getAssets().getLocales();
18784                        }
18785                        bestLocaleIndex = Math.max(0,
18786                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18787                    }
18788                    SystemProperties.set("persist.sys.locale",
18789                            locales.get(bestLocaleIndex).toLanguageTag());
18790                    LocaleList.setDefault(locales, bestLocaleIndex);
18791                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18792                            locales.get(bestLocaleIndex)));
18793                }
18794
18795                mConfigurationSeq++;
18796                if (mConfigurationSeq <= 0) {
18797                    mConfigurationSeq = 1;
18798                }
18799                newConfig.seq = mConfigurationSeq;
18800                mConfiguration = newConfig;
18801                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18802                mUsageStatsService.reportConfigurationChange(newConfig,
18803                        mUserController.getCurrentUserIdLocked());
18804                //mUsageStatsService.noteStartConfig(newConfig);
18805
18806                final Configuration configCopy = new Configuration(mConfiguration);
18807
18808                // TODO: If our config changes, should we auto dismiss any currently
18809                // showing dialogs?
18810                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18811
18812                AttributeCache ac = AttributeCache.instance();
18813                if (ac != null) {
18814                    ac.updateConfiguration(configCopy);
18815                }
18816
18817                // Make sure all resources in our process are updated
18818                // right now, so that anyone who is going to retrieve
18819                // resource values after we return will be sure to get
18820                // the new ones.  This is especially important during
18821                // boot, where the first config change needs to guarantee
18822                // all resources have that config before following boot
18823                // code is executed.
18824                mSystemThread.applyConfigurationToResources(configCopy);
18825
18826                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18827                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18828                    msg.obj = new Configuration(configCopy);
18829                    msg.arg1 = userId;
18830                    mHandler.sendMessage(msg);
18831                }
18832
18833                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18834                if (isDensityChange) {
18835                    // Reset the unsupported display size dialog.
18836                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18837
18838                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18839                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18840                }
18841
18842                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18843                    ProcessRecord app = mLruProcesses.get(i);
18844                    try {
18845                        if (app.thread != null) {
18846                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18847                                    + app.processName + " new config " + mConfiguration);
18848                            app.thread.scheduleConfigurationChanged(configCopy);
18849                        }
18850                    } catch (Exception e) {
18851                    }
18852                }
18853                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18854                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18855                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18856                        | Intent.FLAG_RECEIVER_FOREGROUND);
18857                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18858                        null, AppOpsManager.OP_NONE, null, false, false,
18859                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18860                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18861                    // Tell the shortcut manager that the system locale changed.  It needs to know
18862                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18863                    // we "push" from here, rather than having the service listen to the broadcast.
18864                    final ShortcutServiceInternal shortcutService =
18865                            LocalServices.getService(ShortcutServiceInternal.class);
18866                    if (shortcutService != null) {
18867                        shortcutService.onSystemLocaleChangedNoLock();
18868                    }
18869
18870                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18871                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18872                    if (!mProcessesReady) {
18873                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18874                    }
18875                    broadcastIntentLocked(null, null, intent,
18876                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18877                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18878                }
18879            }
18880            // Update the configuration with WM first and check if any of the stacks need to be
18881            // resized due to the configuration change. If so, resize the stacks now and do any
18882            // relaunches if necessary. This way we don't need to relaunch again below in
18883            // ensureActivityConfigurationLocked().
18884            if (mWindowManager != null) {
18885                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18886                if (resizedStacks != null) {
18887                    for (int stackId : resizedStacks) {
18888                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18889                        mStackSupervisor.resizeStackLocked(
18890                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18891                    }
18892                }
18893            }
18894        }
18895
18896        boolean kept = true;
18897        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18898        // mainStack is null during startup.
18899        if (mainStack != null) {
18900            if (changes != 0 && starting == null) {
18901                // If the configuration changed, and the caller is not already
18902                // in the process of starting an activity, then find the top
18903                // activity to check if its configuration needs to change.
18904                starting = mainStack.topRunningActivityLocked();
18905            }
18906
18907            if (starting != null) {
18908                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18909                // And we need to make sure at this point that all other activities
18910                // are made visible with the correct configuration.
18911                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18912                        !PRESERVE_WINDOWS);
18913            }
18914        }
18915        if (mWindowManager != null) {
18916            mWindowManager.continueSurfaceLayout();
18917        }
18918        return kept;
18919    }
18920
18921    /**
18922     * Decide based on the configuration whether we should shouw the ANR,
18923     * crash, etc dialogs.  The idea is that if there is no affordence to
18924     * press the on-screen buttons, or the user experience would be more
18925     * greatly impacted than the crash itself, we shouldn't show the dialog.
18926     *
18927     * A thought: SystemUI might also want to get told about this, the Power
18928     * dialog / global actions also might want different behaviors.
18929     */
18930    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18931        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18932                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18933                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18934        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18935        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18936                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18937        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18938    }
18939
18940    @Override
18941    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18942        synchronized (this) {
18943            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18944            if (srec != null) {
18945                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18946            }
18947        }
18948        return false;
18949    }
18950
18951    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18952            Intent resultData) {
18953
18954        synchronized (this) {
18955            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18956            if (r != null) {
18957                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18958            }
18959            return false;
18960        }
18961    }
18962
18963    public int getLaunchedFromUid(IBinder activityToken) {
18964        ActivityRecord srec;
18965        synchronized (this) {
18966            srec = ActivityRecord.forTokenLocked(activityToken);
18967        }
18968        if (srec == null) {
18969            return -1;
18970        }
18971        return srec.launchedFromUid;
18972    }
18973
18974    public String getLaunchedFromPackage(IBinder activityToken) {
18975        ActivityRecord srec;
18976        synchronized (this) {
18977            srec = ActivityRecord.forTokenLocked(activityToken);
18978        }
18979        if (srec == null) {
18980            return null;
18981        }
18982        return srec.launchedFromPackage;
18983    }
18984
18985    // =========================================================
18986    // LIFETIME MANAGEMENT
18987    // =========================================================
18988
18989    // Returns which broadcast queue the app is the current [or imminent] receiver
18990    // on, or 'null' if the app is not an active broadcast recipient.
18991    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18992        BroadcastRecord r = app.curReceiver;
18993        if (r != null) {
18994            return r.queue;
18995        }
18996
18997        // It's not the current receiver, but it might be starting up to become one
18998        synchronized (this) {
18999            for (BroadcastQueue queue : mBroadcastQueues) {
19000                r = queue.mPendingBroadcast;
19001                if (r != null && r.curApp == app) {
19002                    // found it; report which queue it's in
19003                    return queue;
19004                }
19005            }
19006        }
19007
19008        return null;
19009    }
19010
19011    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19012            int targetUid, ComponentName targetComponent, String targetProcess) {
19013        if (!mTrackingAssociations) {
19014            return null;
19015        }
19016        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19017                = mAssociations.get(targetUid);
19018        if (components == null) {
19019            components = new ArrayMap<>();
19020            mAssociations.put(targetUid, components);
19021        }
19022        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19023        if (sourceUids == null) {
19024            sourceUids = new SparseArray<>();
19025            components.put(targetComponent, sourceUids);
19026        }
19027        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19028        if (sourceProcesses == null) {
19029            sourceProcesses = new ArrayMap<>();
19030            sourceUids.put(sourceUid, sourceProcesses);
19031        }
19032        Association ass = sourceProcesses.get(sourceProcess);
19033        if (ass == null) {
19034            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19035                    targetProcess);
19036            sourceProcesses.put(sourceProcess, ass);
19037        }
19038        ass.mCount++;
19039        ass.mNesting++;
19040        if (ass.mNesting == 1) {
19041            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19042            ass.mLastState = sourceState;
19043        }
19044        return ass;
19045    }
19046
19047    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19048            ComponentName targetComponent) {
19049        if (!mTrackingAssociations) {
19050            return;
19051        }
19052        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19053                = mAssociations.get(targetUid);
19054        if (components == null) {
19055            return;
19056        }
19057        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19058        if (sourceUids == null) {
19059            return;
19060        }
19061        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19062        if (sourceProcesses == null) {
19063            return;
19064        }
19065        Association ass = sourceProcesses.get(sourceProcess);
19066        if (ass == null || ass.mNesting <= 0) {
19067            return;
19068        }
19069        ass.mNesting--;
19070        if (ass.mNesting == 0) {
19071            long uptime = SystemClock.uptimeMillis();
19072            ass.mTime += uptime - ass.mStartTime;
19073            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19074                    += uptime - ass.mLastStateUptime;
19075            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19076        }
19077    }
19078
19079    private void noteUidProcessState(final int uid, final int state) {
19080        mBatteryStatsService.noteUidProcessState(uid, state);
19081        if (mTrackingAssociations) {
19082            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19083                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19084                        = mAssociations.valueAt(i1);
19085                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19086                    SparseArray<ArrayMap<String, Association>> sourceUids
19087                            = targetComponents.valueAt(i2);
19088                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19089                    if (sourceProcesses != null) {
19090                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19091                            Association ass = sourceProcesses.valueAt(i4);
19092                            if (ass.mNesting >= 1) {
19093                                // currently associated
19094                                long uptime = SystemClock.uptimeMillis();
19095                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19096                                        += uptime - ass.mLastStateUptime;
19097                                ass.mLastState = state;
19098                                ass.mLastStateUptime = uptime;
19099                            }
19100                        }
19101                    }
19102                }
19103            }
19104        }
19105    }
19106
19107    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19108            boolean doingAll, long now) {
19109        if (mAdjSeq == app.adjSeq) {
19110            // This adjustment has already been computed.
19111            return app.curRawAdj;
19112        }
19113
19114        if (app.thread == null) {
19115            app.adjSeq = mAdjSeq;
19116            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19117            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19118            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19119        }
19120
19121        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19122        app.adjSource = null;
19123        app.adjTarget = null;
19124        app.empty = false;
19125        app.cached = false;
19126
19127        final int activitiesSize = app.activities.size();
19128
19129        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19130            // The max adjustment doesn't allow this app to be anything
19131            // below foreground, so it is not worth doing work for it.
19132            app.adjType = "fixed";
19133            app.adjSeq = mAdjSeq;
19134            app.curRawAdj = app.maxAdj;
19135            app.foregroundActivities = false;
19136            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19137            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19138            // System processes can do UI, and when they do we want to have
19139            // them trim their memory after the user leaves the UI.  To
19140            // facilitate this, here we need to determine whether or not it
19141            // is currently showing UI.
19142            app.systemNoUi = true;
19143            if (app == TOP_APP) {
19144                app.systemNoUi = false;
19145                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19146                app.adjType = "pers-top-activity";
19147            } else if (activitiesSize > 0) {
19148                for (int j = 0; j < activitiesSize; j++) {
19149                    final ActivityRecord r = app.activities.get(j);
19150                    if (r.visible) {
19151                        app.systemNoUi = false;
19152                    }
19153                }
19154            }
19155            if (!app.systemNoUi) {
19156                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19157            }
19158            return (app.curAdj=app.maxAdj);
19159        }
19160
19161        app.systemNoUi = false;
19162
19163        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19164
19165        // Determine the importance of the process, starting with most
19166        // important to least, and assign an appropriate OOM adjustment.
19167        int adj;
19168        int schedGroup;
19169        int procState;
19170        boolean foregroundActivities = false;
19171        BroadcastQueue queue;
19172        if (app == TOP_APP) {
19173            // The last app on the list is the foreground app.
19174            adj = ProcessList.FOREGROUND_APP_ADJ;
19175            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19176            app.adjType = "top-activity";
19177            foregroundActivities = true;
19178            procState = PROCESS_STATE_CUR_TOP;
19179        } else if (app.instrumentationClass != null) {
19180            // Don't want to kill running instrumentation.
19181            adj = ProcessList.FOREGROUND_APP_ADJ;
19182            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19183            app.adjType = "instrumentation";
19184            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19185        } else if ((queue = isReceivingBroadcast(app)) != null) {
19186            // An app that is currently receiving a broadcast also
19187            // counts as being in the foreground for OOM killer purposes.
19188            // It's placed in a sched group based on the nature of the
19189            // broadcast as reflected by which queue it's active in.
19190            adj = ProcessList.FOREGROUND_APP_ADJ;
19191            schedGroup = (queue == mFgBroadcastQueue)
19192                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19193            app.adjType = "broadcast";
19194            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19195        } else if (app.executingServices.size() > 0) {
19196            // An app that is currently executing a service callback also
19197            // counts as being in the foreground.
19198            adj = ProcessList.FOREGROUND_APP_ADJ;
19199            schedGroup = app.execServicesFg ?
19200                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19201            app.adjType = "exec-service";
19202            procState = ActivityManager.PROCESS_STATE_SERVICE;
19203            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19204        } else {
19205            // As far as we know the process is empty.  We may change our mind later.
19206            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19207            // At this point we don't actually know the adjustment.  Use the cached adj
19208            // value that the caller wants us to.
19209            adj = cachedAdj;
19210            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19211            app.cached = true;
19212            app.empty = true;
19213            app.adjType = "cch-empty";
19214        }
19215
19216        // Examine all activities if not already foreground.
19217        if (!foregroundActivities && activitiesSize > 0) {
19218            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19219            for (int j = 0; j < activitiesSize; j++) {
19220                final ActivityRecord r = app.activities.get(j);
19221                if (r.app != app) {
19222                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19223                            + " instead of expected " + app);
19224                    if (r.app == null || (r.app.uid == app.uid)) {
19225                        // Only fix things up when they look sane
19226                        r.app = app;
19227                    } else {
19228                        continue;
19229                    }
19230                }
19231                if (r.visible) {
19232                    // App has a visible activity; only upgrade adjustment.
19233                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19234                        adj = ProcessList.VISIBLE_APP_ADJ;
19235                        app.adjType = "visible";
19236                    }
19237                    if (procState > PROCESS_STATE_CUR_TOP) {
19238                        procState = PROCESS_STATE_CUR_TOP;
19239                    }
19240                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19241                    app.cached = false;
19242                    app.empty = false;
19243                    foregroundActivities = true;
19244                    if (r.task != null && minLayer > 0) {
19245                        final int layer = r.task.mLayerRank;
19246                        if (layer >= 0 && minLayer > layer) {
19247                            minLayer = layer;
19248                        }
19249                    }
19250                    break;
19251                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19252                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19253                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19254                        app.adjType = "pausing";
19255                    }
19256                    if (procState > PROCESS_STATE_CUR_TOP) {
19257                        procState = PROCESS_STATE_CUR_TOP;
19258                    }
19259                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19260                    app.cached = false;
19261                    app.empty = false;
19262                    foregroundActivities = true;
19263                } else if (r.state == ActivityState.STOPPING) {
19264                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19265                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19266                        app.adjType = "stopping";
19267                    }
19268                    // For the process state, we will at this point consider the
19269                    // process to be cached.  It will be cached either as an activity
19270                    // or empty depending on whether the activity is finishing.  We do
19271                    // this so that we can treat the process as cached for purposes of
19272                    // memory trimming (determing current memory level, trim command to
19273                    // send to process) since there can be an arbitrary number of stopping
19274                    // processes and they should soon all go into the cached state.
19275                    if (!r.finishing) {
19276                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19277                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19278                        }
19279                    }
19280                    app.cached = false;
19281                    app.empty = false;
19282                    foregroundActivities = true;
19283                } else {
19284                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19285                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19286                        app.adjType = "cch-act";
19287                    }
19288                }
19289            }
19290            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19291                adj += minLayer;
19292            }
19293        }
19294
19295        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19296                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19297            if (app.foregroundServices) {
19298                // The user is aware of this app, so make it visible.
19299                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19300                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19301                app.cached = false;
19302                app.adjType = "fg-service";
19303                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19304            } else if (app.forcingToForeground != null) {
19305                // The user is aware of this app, so make it visible.
19306                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19307                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19308                app.cached = false;
19309                app.adjType = "force-fg";
19310                app.adjSource = app.forcingToForeground;
19311                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19312            }
19313        }
19314
19315        if (app == mHeavyWeightProcess) {
19316            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19317                // We don't want to kill the current heavy-weight process.
19318                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19319                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19320                app.cached = false;
19321                app.adjType = "heavy";
19322            }
19323            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19324                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19325            }
19326        }
19327
19328        if (app == mHomeProcess) {
19329            if (adj > ProcessList.HOME_APP_ADJ) {
19330                // This process is hosting what we currently consider to be the
19331                // home app, so we don't want to let it go into the background.
19332                adj = ProcessList.HOME_APP_ADJ;
19333                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19334                app.cached = false;
19335                app.adjType = "home";
19336            }
19337            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19338                procState = ActivityManager.PROCESS_STATE_HOME;
19339            }
19340        }
19341
19342        if (app == mPreviousProcess && app.activities.size() > 0) {
19343            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19344                // This was the previous process that showed UI to the user.
19345                // We want to try to keep it around more aggressively, to give
19346                // a good experience around switching between two apps.
19347                adj = ProcessList.PREVIOUS_APP_ADJ;
19348                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19349                app.cached = false;
19350                app.adjType = "previous";
19351            }
19352            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19353                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19354            }
19355        }
19356
19357        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19358                + " reason=" + app.adjType);
19359
19360        // By default, we use the computed adjustment.  It may be changed if
19361        // there are applications dependent on our services or providers, but
19362        // this gives us a baseline and makes sure we don't get into an
19363        // infinite recursion.
19364        app.adjSeq = mAdjSeq;
19365        app.curRawAdj = adj;
19366        app.hasStartedServices = false;
19367
19368        if (mBackupTarget != null && app == mBackupTarget.app) {
19369            // If possible we want to avoid killing apps while they're being backed up
19370            if (adj > ProcessList.BACKUP_APP_ADJ) {
19371                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19372                adj = ProcessList.BACKUP_APP_ADJ;
19373                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19374                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19375                }
19376                app.adjType = "backup";
19377                app.cached = false;
19378            }
19379            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19380                procState = ActivityManager.PROCESS_STATE_BACKUP;
19381            }
19382        }
19383
19384        boolean mayBeTop = false;
19385
19386        for (int is = app.services.size()-1;
19387                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19388                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19389                        || procState > ActivityManager.PROCESS_STATE_TOP);
19390                is--) {
19391            ServiceRecord s = app.services.valueAt(is);
19392            if (s.startRequested) {
19393                app.hasStartedServices = true;
19394                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19395                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19396                }
19397                if (app.hasShownUi && app != mHomeProcess) {
19398                    // If this process has shown some UI, let it immediately
19399                    // go to the LRU list because it may be pretty heavy with
19400                    // UI stuff.  We'll tag it with a label just to help
19401                    // debug and understand what is going on.
19402                    if (adj > ProcessList.SERVICE_ADJ) {
19403                        app.adjType = "cch-started-ui-services";
19404                    }
19405                } else {
19406                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19407                        // This service has seen some activity within
19408                        // recent memory, so we will keep its process ahead
19409                        // of the background processes.
19410                        if (adj > ProcessList.SERVICE_ADJ) {
19411                            adj = ProcessList.SERVICE_ADJ;
19412                            app.adjType = "started-services";
19413                            app.cached = false;
19414                        }
19415                    }
19416                    // If we have let the service slide into the background
19417                    // state, still have some text describing what it is doing
19418                    // even though the service no longer has an impact.
19419                    if (adj > ProcessList.SERVICE_ADJ) {
19420                        app.adjType = "cch-started-services";
19421                    }
19422                }
19423            }
19424
19425            for (int conni = s.connections.size()-1;
19426                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19427                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19428                            || procState > ActivityManager.PROCESS_STATE_TOP);
19429                    conni--) {
19430                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19431                for (int i = 0;
19432                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19433                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19434                                || procState > ActivityManager.PROCESS_STATE_TOP);
19435                        i++) {
19436                    // XXX should compute this based on the max of
19437                    // all connected clients.
19438                    ConnectionRecord cr = clist.get(i);
19439                    if (cr.binding.client == app) {
19440                        // Binding to ourself is not interesting.
19441                        continue;
19442                    }
19443
19444                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19445                        ProcessRecord client = cr.binding.client;
19446                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19447                                TOP_APP, doingAll, now);
19448                        int clientProcState = client.curProcState;
19449                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19450                            // If the other app is cached for any reason, for purposes here
19451                            // we are going to consider it empty.  The specific cached state
19452                            // doesn't propagate except under certain conditions.
19453                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19454                        }
19455                        String adjType = null;
19456                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19457                            // Not doing bind OOM management, so treat
19458                            // this guy more like a started service.
19459                            if (app.hasShownUi && app != mHomeProcess) {
19460                                // If this process has shown some UI, let it immediately
19461                                // go to the LRU list because it may be pretty heavy with
19462                                // UI stuff.  We'll tag it with a label just to help
19463                                // debug and understand what is going on.
19464                                if (adj > clientAdj) {
19465                                    adjType = "cch-bound-ui-services";
19466                                }
19467                                app.cached = false;
19468                                clientAdj = adj;
19469                                clientProcState = procState;
19470                            } else {
19471                                if (now >= (s.lastActivity
19472                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19473                                    // This service has not seen activity within
19474                                    // recent memory, so allow it to drop to the
19475                                    // LRU list if there is no other reason to keep
19476                                    // it around.  We'll also tag it with a label just
19477                                    // to help debug and undertand what is going on.
19478                                    if (adj > clientAdj) {
19479                                        adjType = "cch-bound-services";
19480                                    }
19481                                    clientAdj = adj;
19482                                }
19483                            }
19484                        }
19485                        if (adj > clientAdj) {
19486                            // If this process has recently shown UI, and
19487                            // the process that is binding to it is less
19488                            // important than being visible, then we don't
19489                            // care about the binding as much as we care
19490                            // about letting this process get into the LRU
19491                            // list to be killed and restarted if needed for
19492                            // memory.
19493                            if (app.hasShownUi && app != mHomeProcess
19494                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19495                                adjType = "cch-bound-ui-services";
19496                            } else {
19497                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19498                                        |Context.BIND_IMPORTANT)) != 0) {
19499                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19500                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19501                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19502                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19503                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19504                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19505                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19506                                    adj = clientAdj;
19507                                } else {
19508                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19509                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19510                                    }
19511                                }
19512                                if (!client.cached) {
19513                                    app.cached = false;
19514                                }
19515                                adjType = "service";
19516                            }
19517                        }
19518                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19519                            // This will treat important bound services identically to
19520                            // the top app, which may behave differently than generic
19521                            // foreground work.
19522                            if (client.curSchedGroup > schedGroup) {
19523                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19524                                    schedGroup = client.curSchedGroup;
19525                                } else {
19526                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19527                                }
19528                            }
19529                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19530                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19531                                    // Special handling of clients who are in the top state.
19532                                    // We *may* want to consider this process to be in the
19533                                    // top state as well, but only if there is not another
19534                                    // reason for it to be running.  Being on the top is a
19535                                    // special state, meaning you are specifically running
19536                                    // for the current top app.  If the process is already
19537                                    // running in the background for some other reason, it
19538                                    // is more important to continue considering it to be
19539                                    // in the background state.
19540                                    mayBeTop = true;
19541                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19542                                } else {
19543                                    // Special handling for above-top states (persistent
19544                                    // processes).  These should not bring the current process
19545                                    // into the top state, since they are not on top.  Instead
19546                                    // give them the best state after that.
19547                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19548                                        clientProcState =
19549                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19550                                    } else if (mWakefulness
19551                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19552                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19553                                                    != 0) {
19554                                        clientProcState =
19555                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19556                                    } else {
19557                                        clientProcState =
19558                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19559                                    }
19560                                }
19561                            }
19562                        } else {
19563                            if (clientProcState <
19564                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19565                                clientProcState =
19566                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19567                            }
19568                        }
19569                        if (procState > clientProcState) {
19570                            procState = clientProcState;
19571                        }
19572                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19573                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19574                            app.pendingUiClean = true;
19575                        }
19576                        if (adjType != null) {
19577                            app.adjType = adjType;
19578                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19579                                    .REASON_SERVICE_IN_USE;
19580                            app.adjSource = cr.binding.client;
19581                            app.adjSourceProcState = clientProcState;
19582                            app.adjTarget = s.name;
19583                        }
19584                    }
19585                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19586                        app.treatLikeActivity = true;
19587                    }
19588                    final ActivityRecord a = cr.activity;
19589                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19590                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19591                            (a.visible || a.state == ActivityState.RESUMED ||
19592                             a.state == ActivityState.PAUSING)) {
19593                            adj = ProcessList.FOREGROUND_APP_ADJ;
19594                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19595                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19596                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19597                                } else {
19598                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19599                                }
19600                            }
19601                            app.cached = false;
19602                            app.adjType = "service";
19603                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19604                                    .REASON_SERVICE_IN_USE;
19605                            app.adjSource = a;
19606                            app.adjSourceProcState = procState;
19607                            app.adjTarget = s.name;
19608                        }
19609                    }
19610                }
19611            }
19612        }
19613
19614        for (int provi = app.pubProviders.size()-1;
19615                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19616                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19617                        || procState > ActivityManager.PROCESS_STATE_TOP);
19618                provi--) {
19619            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19620            for (int i = cpr.connections.size()-1;
19621                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19622                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19623                            || procState > ActivityManager.PROCESS_STATE_TOP);
19624                    i--) {
19625                ContentProviderConnection conn = cpr.connections.get(i);
19626                ProcessRecord client = conn.client;
19627                if (client == app) {
19628                    // Being our own client is not interesting.
19629                    continue;
19630                }
19631                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19632                int clientProcState = client.curProcState;
19633                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19634                    // If the other app is cached for any reason, for purposes here
19635                    // we are going to consider it empty.
19636                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19637                }
19638                if (adj > clientAdj) {
19639                    if (app.hasShownUi && app != mHomeProcess
19640                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19641                        app.adjType = "cch-ui-provider";
19642                    } else {
19643                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19644                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19645                        app.adjType = "provider";
19646                    }
19647                    app.cached &= client.cached;
19648                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19649                            .REASON_PROVIDER_IN_USE;
19650                    app.adjSource = client;
19651                    app.adjSourceProcState = clientProcState;
19652                    app.adjTarget = cpr.name;
19653                }
19654                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19655                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19656                        // Special handling of clients who are in the top state.
19657                        // We *may* want to consider this process to be in the
19658                        // top state as well, but only if there is not another
19659                        // reason for it to be running.  Being on the top is a
19660                        // special state, meaning you are specifically running
19661                        // for the current top app.  If the process is already
19662                        // running in the background for some other reason, it
19663                        // is more important to continue considering it to be
19664                        // in the background state.
19665                        mayBeTop = true;
19666                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19667                    } else {
19668                        // Special handling for above-top states (persistent
19669                        // processes).  These should not bring the current process
19670                        // into the top state, since they are not on top.  Instead
19671                        // give them the best state after that.
19672                        clientProcState =
19673                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19674                    }
19675                }
19676                if (procState > clientProcState) {
19677                    procState = clientProcState;
19678                }
19679                if (client.curSchedGroup > schedGroup) {
19680                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19681                }
19682            }
19683            // If the provider has external (non-framework) process
19684            // dependencies, ensure that its adjustment is at least
19685            // FOREGROUND_APP_ADJ.
19686            if (cpr.hasExternalProcessHandles()) {
19687                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19688                    adj = ProcessList.FOREGROUND_APP_ADJ;
19689                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19690                    app.cached = false;
19691                    app.adjType = "provider";
19692                    app.adjTarget = cpr.name;
19693                }
19694                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19695                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19696                }
19697            }
19698        }
19699
19700        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19701            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19702                adj = ProcessList.PREVIOUS_APP_ADJ;
19703                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19704                app.cached = false;
19705                app.adjType = "provider";
19706            }
19707            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19708                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19709            }
19710        }
19711
19712        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19713            // A client of one of our services or providers is in the top state.  We
19714            // *may* want to be in the top state, but not if we are already running in
19715            // the background for some other reason.  For the decision here, we are going
19716            // to pick out a few specific states that we want to remain in when a client
19717            // is top (states that tend to be longer-term) and otherwise allow it to go
19718            // to the top state.
19719            switch (procState) {
19720                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19721                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19722                case ActivityManager.PROCESS_STATE_SERVICE:
19723                    // These all are longer-term states, so pull them up to the top
19724                    // of the background states, but not all the way to the top state.
19725                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19726                    break;
19727                default:
19728                    // Otherwise, top is a better choice, so take it.
19729                    procState = ActivityManager.PROCESS_STATE_TOP;
19730                    break;
19731            }
19732        }
19733
19734        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19735            if (app.hasClientActivities) {
19736                // This is a cached process, but with client activities.  Mark it so.
19737                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19738                app.adjType = "cch-client-act";
19739            } else if (app.treatLikeActivity) {
19740                // This is a cached process, but somebody wants us to treat it like it has
19741                // an activity, okay!
19742                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19743                app.adjType = "cch-as-act";
19744            }
19745        }
19746
19747        if (adj == ProcessList.SERVICE_ADJ) {
19748            if (doingAll) {
19749                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19750                mNewNumServiceProcs++;
19751                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19752                if (!app.serviceb) {
19753                    // This service isn't far enough down on the LRU list to
19754                    // normally be a B service, but if we are low on RAM and it
19755                    // is large we want to force it down since we would prefer to
19756                    // keep launcher over it.
19757                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19758                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19759                        app.serviceHighRam = true;
19760                        app.serviceb = true;
19761                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19762                    } else {
19763                        mNewNumAServiceProcs++;
19764                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19765                    }
19766                } else {
19767                    app.serviceHighRam = false;
19768                }
19769            }
19770            if (app.serviceb) {
19771                adj = ProcessList.SERVICE_B_ADJ;
19772            }
19773        }
19774
19775        app.curRawAdj = adj;
19776
19777        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19778        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19779        if (adj > app.maxAdj) {
19780            adj = app.maxAdj;
19781            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19782                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19783            }
19784        }
19785
19786        // Do final modification to adj.  Everything we do between here and applying
19787        // the final setAdj must be done in this function, because we will also use
19788        // it when computing the final cached adj later.  Note that we don't need to
19789        // worry about this for max adj above, since max adj will always be used to
19790        // keep it out of the cached vaues.
19791        app.curAdj = app.modifyRawOomAdj(adj);
19792        app.curSchedGroup = schedGroup;
19793        app.curProcState = procState;
19794        app.foregroundActivities = foregroundActivities;
19795
19796        return app.curRawAdj;
19797    }
19798
19799    /**
19800     * Record new PSS sample for a process.
19801     */
19802    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19803            long now) {
19804        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19805                swapPss * 1024);
19806        proc.lastPssTime = now;
19807        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19808        if (DEBUG_PSS) Slog.d(TAG_PSS,
19809                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19810                + " state=" + ProcessList.makeProcStateString(procState));
19811        if (proc.initialIdlePss == 0) {
19812            proc.initialIdlePss = pss;
19813        }
19814        proc.lastPss = pss;
19815        proc.lastSwapPss = swapPss;
19816        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19817            proc.lastCachedPss = pss;
19818            proc.lastCachedSwapPss = swapPss;
19819        }
19820
19821        final SparseArray<Pair<Long, String>> watchUids
19822                = mMemWatchProcesses.getMap().get(proc.processName);
19823        Long check = null;
19824        if (watchUids != null) {
19825            Pair<Long, String> val = watchUids.get(proc.uid);
19826            if (val == null) {
19827                val = watchUids.get(0);
19828            }
19829            if (val != null) {
19830                check = val.first;
19831            }
19832        }
19833        if (check != null) {
19834            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19835                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19836                if (!isDebuggable) {
19837                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19838                        isDebuggable = true;
19839                    }
19840                }
19841                if (isDebuggable) {
19842                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19843                    final ProcessRecord myProc = proc;
19844                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19845                    mMemWatchDumpProcName = proc.processName;
19846                    mMemWatchDumpFile = heapdumpFile.toString();
19847                    mMemWatchDumpPid = proc.pid;
19848                    mMemWatchDumpUid = proc.uid;
19849                    BackgroundThread.getHandler().post(new Runnable() {
19850                        @Override
19851                        public void run() {
19852                            revokeUriPermission(ActivityThread.currentActivityThread()
19853                                            .getApplicationThread(),
19854                                    DumpHeapActivity.JAVA_URI,
19855                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19856                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19857                                    UserHandle.myUserId());
19858                            ParcelFileDescriptor fd = null;
19859                            try {
19860                                heapdumpFile.delete();
19861                                fd = ParcelFileDescriptor.open(heapdumpFile,
19862                                        ParcelFileDescriptor.MODE_CREATE |
19863                                                ParcelFileDescriptor.MODE_TRUNCATE |
19864                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19865                                                ParcelFileDescriptor.MODE_APPEND);
19866                                IApplicationThread thread = myProc.thread;
19867                                if (thread != null) {
19868                                    try {
19869                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19870                                                "Requesting dump heap from "
19871                                                + myProc + " to " + heapdumpFile);
19872                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19873                                    } catch (RemoteException e) {
19874                                    }
19875                                }
19876                            } catch (FileNotFoundException e) {
19877                                e.printStackTrace();
19878                            } finally {
19879                                if (fd != null) {
19880                                    try {
19881                                        fd.close();
19882                                    } catch (IOException e) {
19883                                    }
19884                                }
19885                            }
19886                        }
19887                    });
19888                } else {
19889                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19890                            + ", but debugging not enabled");
19891                }
19892            }
19893        }
19894    }
19895
19896    /**
19897     * Schedule PSS collection of a process.
19898     */
19899    void requestPssLocked(ProcessRecord proc, int procState) {
19900        if (mPendingPssProcesses.contains(proc)) {
19901            return;
19902        }
19903        if (mPendingPssProcesses.size() == 0) {
19904            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19905        }
19906        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19907        proc.pssProcState = procState;
19908        mPendingPssProcesses.add(proc);
19909    }
19910
19911    /**
19912     * Schedule PSS collection of all processes.
19913     */
19914    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19915        if (!always) {
19916            if (now < (mLastFullPssTime +
19917                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19918                return;
19919            }
19920        }
19921        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19922        mLastFullPssTime = now;
19923        mFullPssPending = true;
19924        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19925        mPendingPssProcesses.clear();
19926        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19927            ProcessRecord app = mLruProcesses.get(i);
19928            if (app.thread == null
19929                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19930                continue;
19931            }
19932            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19933                app.pssProcState = app.setProcState;
19934                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19935                        mTestPssMode, isSleepingLocked(), now);
19936                mPendingPssProcesses.add(app);
19937            }
19938        }
19939        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19940    }
19941
19942    public void setTestPssMode(boolean enabled) {
19943        synchronized (this) {
19944            mTestPssMode = enabled;
19945            if (enabled) {
19946                // Whenever we enable the mode, we want to take a snapshot all of current
19947                // process mem use.
19948                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19949            }
19950        }
19951    }
19952
19953    /**
19954     * Ask a given process to GC right now.
19955     */
19956    final void performAppGcLocked(ProcessRecord app) {
19957        try {
19958            app.lastRequestedGc = SystemClock.uptimeMillis();
19959            if (app.thread != null) {
19960                if (app.reportLowMemory) {
19961                    app.reportLowMemory = false;
19962                    app.thread.scheduleLowMemory();
19963                } else {
19964                    app.thread.processInBackground();
19965                }
19966            }
19967        } catch (Exception e) {
19968            // whatever.
19969        }
19970    }
19971
19972    /**
19973     * Returns true if things are idle enough to perform GCs.
19974     */
19975    private final boolean canGcNowLocked() {
19976        boolean processingBroadcasts = false;
19977        for (BroadcastQueue q : mBroadcastQueues) {
19978            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19979                processingBroadcasts = true;
19980            }
19981        }
19982        return !processingBroadcasts
19983                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19984    }
19985
19986    /**
19987     * Perform GCs on all processes that are waiting for it, but only
19988     * if things are idle.
19989     */
19990    final void performAppGcsLocked() {
19991        final int N = mProcessesToGc.size();
19992        if (N <= 0) {
19993            return;
19994        }
19995        if (canGcNowLocked()) {
19996            while (mProcessesToGc.size() > 0) {
19997                ProcessRecord proc = mProcessesToGc.remove(0);
19998                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19999                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20000                            <= SystemClock.uptimeMillis()) {
20001                        // To avoid spamming the system, we will GC processes one
20002                        // at a time, waiting a few seconds between each.
20003                        performAppGcLocked(proc);
20004                        scheduleAppGcsLocked();
20005                        return;
20006                    } else {
20007                        // It hasn't been long enough since we last GCed this
20008                        // process...  put it in the list to wait for its time.
20009                        addProcessToGcListLocked(proc);
20010                        break;
20011                    }
20012                }
20013            }
20014
20015            scheduleAppGcsLocked();
20016        }
20017    }
20018
20019    /**
20020     * If all looks good, perform GCs on all processes waiting for them.
20021     */
20022    final void performAppGcsIfAppropriateLocked() {
20023        if (canGcNowLocked()) {
20024            performAppGcsLocked();
20025            return;
20026        }
20027        // Still not idle, wait some more.
20028        scheduleAppGcsLocked();
20029    }
20030
20031    /**
20032     * Schedule the execution of all pending app GCs.
20033     */
20034    final void scheduleAppGcsLocked() {
20035        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20036
20037        if (mProcessesToGc.size() > 0) {
20038            // Schedule a GC for the time to the next process.
20039            ProcessRecord proc = mProcessesToGc.get(0);
20040            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20041
20042            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20043            long now = SystemClock.uptimeMillis();
20044            if (when < (now+GC_TIMEOUT)) {
20045                when = now + GC_TIMEOUT;
20046            }
20047            mHandler.sendMessageAtTime(msg, when);
20048        }
20049    }
20050
20051    /**
20052     * Add a process to the array of processes waiting to be GCed.  Keeps the
20053     * list in sorted order by the last GC time.  The process can't already be
20054     * on the list.
20055     */
20056    final void addProcessToGcListLocked(ProcessRecord proc) {
20057        boolean added = false;
20058        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20059            if (mProcessesToGc.get(i).lastRequestedGc <
20060                    proc.lastRequestedGc) {
20061                added = true;
20062                mProcessesToGc.add(i+1, proc);
20063                break;
20064            }
20065        }
20066        if (!added) {
20067            mProcessesToGc.add(0, proc);
20068        }
20069    }
20070
20071    /**
20072     * Set up to ask a process to GC itself.  This will either do it
20073     * immediately, or put it on the list of processes to gc the next
20074     * time things are idle.
20075     */
20076    final void scheduleAppGcLocked(ProcessRecord app) {
20077        long now = SystemClock.uptimeMillis();
20078        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20079            return;
20080        }
20081        if (!mProcessesToGc.contains(app)) {
20082            addProcessToGcListLocked(app);
20083            scheduleAppGcsLocked();
20084        }
20085    }
20086
20087    final void checkExcessivePowerUsageLocked(boolean doKills) {
20088        updateCpuStatsNow();
20089
20090        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20091        boolean doWakeKills = doKills;
20092        boolean doCpuKills = doKills;
20093        if (mLastPowerCheckRealtime == 0) {
20094            doWakeKills = false;
20095        }
20096        if (mLastPowerCheckUptime == 0) {
20097            doCpuKills = false;
20098        }
20099        if (stats.isScreenOn()) {
20100            doWakeKills = false;
20101        }
20102        final long curRealtime = SystemClock.elapsedRealtime();
20103        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20104        final long curUptime = SystemClock.uptimeMillis();
20105        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20106        mLastPowerCheckRealtime = curRealtime;
20107        mLastPowerCheckUptime = curUptime;
20108        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20109            doWakeKills = false;
20110        }
20111        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20112            doCpuKills = false;
20113        }
20114        int i = mLruProcesses.size();
20115        while (i > 0) {
20116            i--;
20117            ProcessRecord app = mLruProcesses.get(i);
20118            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20119                long wtime;
20120                synchronized (stats) {
20121                    wtime = stats.getProcessWakeTime(app.info.uid,
20122                            app.pid, curRealtime);
20123                }
20124                long wtimeUsed = wtime - app.lastWakeTime;
20125                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20126                if (DEBUG_POWER) {
20127                    StringBuilder sb = new StringBuilder(128);
20128                    sb.append("Wake for ");
20129                    app.toShortString(sb);
20130                    sb.append(": over ");
20131                    TimeUtils.formatDuration(realtimeSince, sb);
20132                    sb.append(" used ");
20133                    TimeUtils.formatDuration(wtimeUsed, sb);
20134                    sb.append(" (");
20135                    sb.append((wtimeUsed*100)/realtimeSince);
20136                    sb.append("%)");
20137                    Slog.i(TAG_POWER, sb.toString());
20138                    sb.setLength(0);
20139                    sb.append("CPU for ");
20140                    app.toShortString(sb);
20141                    sb.append(": over ");
20142                    TimeUtils.formatDuration(uptimeSince, sb);
20143                    sb.append(" used ");
20144                    TimeUtils.formatDuration(cputimeUsed, sb);
20145                    sb.append(" (");
20146                    sb.append((cputimeUsed*100)/uptimeSince);
20147                    sb.append("%)");
20148                    Slog.i(TAG_POWER, sb.toString());
20149                }
20150                // If a process has held a wake lock for more
20151                // than 50% of the time during this period,
20152                // that sounds bad.  Kill!
20153                if (doWakeKills && realtimeSince > 0
20154                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20155                    synchronized (stats) {
20156                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20157                                realtimeSince, wtimeUsed);
20158                    }
20159                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20160                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20161                } else if (doCpuKills && uptimeSince > 0
20162                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20163                    synchronized (stats) {
20164                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20165                                uptimeSince, cputimeUsed);
20166                    }
20167                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20168                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20169                } else {
20170                    app.lastWakeTime = wtime;
20171                    app.lastCpuTime = app.curCpuTime;
20172                }
20173            }
20174        }
20175    }
20176
20177    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20178            long nowElapsed) {
20179        boolean success = true;
20180
20181        if (app.curRawAdj != app.setRawAdj) {
20182            app.setRawAdj = app.curRawAdj;
20183        }
20184
20185        int changes = 0;
20186
20187        if (app.curAdj != app.setAdj) {
20188            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20189            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20190                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20191                    + app.adjType);
20192            app.setAdj = app.curAdj;
20193            app.verifiedAdj = ProcessList.INVALID_ADJ;
20194        }
20195
20196        if (app.setSchedGroup != app.curSchedGroup) {
20197            int oldSchedGroup = app.setSchedGroup;
20198            app.setSchedGroup = app.curSchedGroup;
20199            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20200                    "Setting sched group of " + app.processName
20201                    + " to " + app.curSchedGroup);
20202            if (app.waitingToKill != null && app.curReceiver == null
20203                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20204                app.kill(app.waitingToKill, true);
20205                success = false;
20206            } else {
20207                int processGroup;
20208                switch (app.curSchedGroup) {
20209                    case ProcessList.SCHED_GROUP_BACKGROUND:
20210                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20211                        break;
20212                    case ProcessList.SCHED_GROUP_TOP_APP:
20213                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20214                        processGroup = Process.THREAD_GROUP_TOP_APP;
20215                        break;
20216                    default:
20217                        processGroup = Process.THREAD_GROUP_DEFAULT;
20218                        break;
20219                }
20220                long oldId = Binder.clearCallingIdentity();
20221                try {
20222                    Process.setProcessGroup(app.pid, processGroup);
20223                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20224                        // do nothing if we already switched to RT
20225                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20226                            // Switch VR thread for app to SCHED_FIFO
20227                            if (mInVrMode && app.vrThreadTid != 0) {
20228                                Process.setThreadScheduler(app.vrThreadTid,
20229                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20230                            }
20231                            if (mUseFifoUiScheduling) {
20232                                // Switch UI pipeline for app to SCHED_FIFO
20233                                app.savedPriority = Process.getThreadPriority(app.pid);
20234                                Process.setThreadScheduler(app.pid,
20235                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20236                                if (app.renderThreadTid != 0) {
20237                                    Process.setThreadScheduler(app.renderThreadTid,
20238                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20239                                    if (DEBUG_OOM_ADJ) {
20240                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20241                                            app.renderThreadTid + ") to FIFO");
20242                                    }
20243                                } else {
20244                                    if (DEBUG_OOM_ADJ) {
20245                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20246                                    }
20247                                }
20248                            }
20249                        }
20250                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20251                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20252                        // Reset VR thread to SCHED_OTHER
20253                        // Safe to do even if we're not in VR mode
20254                        if (app.vrThreadTid != 0) {
20255                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20256                        }
20257                        if (mUseFifoUiScheduling) {
20258                            // Reset UI pipeline to SCHED_OTHER
20259                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20260                            Process.setThreadScheduler(app.renderThreadTid,
20261                                Process.SCHED_OTHER, 0);
20262                            Process.setThreadPriority(app.pid, app.savedPriority);
20263                            Process.setThreadPriority(app.renderThreadTid, -4);
20264                        }
20265                    }
20266                } catch (Exception e) {
20267                    Slog.w(TAG, "Failed setting process group of " + app.pid
20268                            + " to " + app.curSchedGroup);
20269                    e.printStackTrace();
20270                } finally {
20271                    Binder.restoreCallingIdentity(oldId);
20272                }
20273            }
20274        }
20275        if (app.repForegroundActivities != app.foregroundActivities) {
20276            app.repForegroundActivities = app.foregroundActivities;
20277            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20278        }
20279        if (app.repProcState != app.curProcState) {
20280            app.repProcState = app.curProcState;
20281            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20282            if (app.thread != null) {
20283                try {
20284                    if (false) {
20285                        //RuntimeException h = new RuntimeException("here");
20286                        Slog.i(TAG, "Sending new process state " + app.repProcState
20287                                + " to " + app /*, h*/);
20288                    }
20289                    app.thread.setProcessState(app.repProcState);
20290                } catch (RemoteException e) {
20291                }
20292            }
20293        }
20294        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20295                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20296            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20297                // Experimental code to more aggressively collect pss while
20298                // running test...  the problem is that this tends to collect
20299                // the data right when a process is transitioning between process
20300                // states, which well tend to give noisy data.
20301                long start = SystemClock.uptimeMillis();
20302                long pss = Debug.getPss(app.pid, mTmpLong, null);
20303                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20304                mPendingPssProcesses.remove(app);
20305                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20306                        + " to " + app.curProcState + ": "
20307                        + (SystemClock.uptimeMillis()-start) + "ms");
20308            }
20309            app.lastStateTime = now;
20310            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20311                    mTestPssMode, isSleepingLocked(), now);
20312            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20313                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20314                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20315                    + (app.nextPssTime-now) + ": " + app);
20316        } else {
20317            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20318                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20319                    mTestPssMode)))) {
20320                requestPssLocked(app, app.setProcState);
20321                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20322                        mTestPssMode, isSleepingLocked(), now);
20323            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20324                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20325        }
20326        if (app.setProcState != app.curProcState) {
20327            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20328                    "Proc state change of " + app.processName
20329                            + " to " + app.curProcState);
20330            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20331            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20332            if (setImportant && !curImportant) {
20333                // This app is no longer something we consider important enough to allow to
20334                // use arbitrary amounts of battery power.  Note
20335                // its current wake lock time to later know to kill it if
20336                // it is not behaving well.
20337                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20338                synchronized (stats) {
20339                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20340                            app.pid, nowElapsed);
20341                }
20342                app.lastCpuTime = app.curCpuTime;
20343
20344            }
20345            // Inform UsageStats of important process state change
20346            // Must be called before updating setProcState
20347            maybeUpdateUsageStatsLocked(app, nowElapsed);
20348
20349            app.setProcState = app.curProcState;
20350            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20351                app.notCachedSinceIdle = false;
20352            }
20353            if (!doingAll) {
20354                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20355            } else {
20356                app.procStateChanged = true;
20357            }
20358        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20359                > USAGE_STATS_INTERACTION_INTERVAL) {
20360            // For apps that sit around for a long time in the interactive state, we need
20361            // to report this at least once a day so they don't go idle.
20362            maybeUpdateUsageStatsLocked(app, nowElapsed);
20363        }
20364
20365        if (changes != 0) {
20366            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20367                    "Changes in " + app + ": " + changes);
20368            int i = mPendingProcessChanges.size()-1;
20369            ProcessChangeItem item = null;
20370            while (i >= 0) {
20371                item = mPendingProcessChanges.get(i);
20372                if (item.pid == app.pid) {
20373                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20374                            "Re-using existing item: " + item);
20375                    break;
20376                }
20377                i--;
20378            }
20379            if (i < 0) {
20380                // No existing item in pending changes; need a new one.
20381                final int NA = mAvailProcessChanges.size();
20382                if (NA > 0) {
20383                    item = mAvailProcessChanges.remove(NA-1);
20384                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20385                            "Retrieving available item: " + item);
20386                } else {
20387                    item = new ProcessChangeItem();
20388                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20389                            "Allocating new item: " + item);
20390                }
20391                item.changes = 0;
20392                item.pid = app.pid;
20393                item.uid = app.info.uid;
20394                if (mPendingProcessChanges.size() == 0) {
20395                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20396                            "*** Enqueueing dispatch processes changed!");
20397                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20398                }
20399                mPendingProcessChanges.add(item);
20400            }
20401            item.changes |= changes;
20402            item.processState = app.repProcState;
20403            item.foregroundActivities = app.repForegroundActivities;
20404            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20405                    "Item " + Integer.toHexString(System.identityHashCode(item))
20406                    + " " + app.toShortString() + ": changes=" + item.changes
20407                    + " procState=" + item.processState
20408                    + " foreground=" + item.foregroundActivities
20409                    + " type=" + app.adjType + " source=" + app.adjSource
20410                    + " target=" + app.adjTarget);
20411        }
20412
20413        return success;
20414    }
20415
20416    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20417        final UidRecord.ChangeItem pendingChange;
20418        if (uidRec == null || uidRec.pendingChange == null) {
20419            if (mPendingUidChanges.size() == 0) {
20420                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20421                        "*** Enqueueing dispatch uid changed!");
20422                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20423            }
20424            final int NA = mAvailUidChanges.size();
20425            if (NA > 0) {
20426                pendingChange = mAvailUidChanges.remove(NA-1);
20427                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20428                        "Retrieving available item: " + pendingChange);
20429            } else {
20430                pendingChange = new UidRecord.ChangeItem();
20431                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20432                        "Allocating new item: " + pendingChange);
20433            }
20434            if (uidRec != null) {
20435                uidRec.pendingChange = pendingChange;
20436                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20437                    // If this uid is going away, and we haven't yet reported it is gone,
20438                    // then do so now.
20439                    change = UidRecord.CHANGE_GONE_IDLE;
20440                }
20441            } else if (uid < 0) {
20442                throw new IllegalArgumentException("No UidRecord or uid");
20443            }
20444            pendingChange.uidRecord = uidRec;
20445            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20446            mPendingUidChanges.add(pendingChange);
20447        } else {
20448            pendingChange = uidRec.pendingChange;
20449            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20450                change = UidRecord.CHANGE_GONE_IDLE;
20451            }
20452        }
20453        pendingChange.change = change;
20454        pendingChange.processState = uidRec != null
20455                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20456    }
20457
20458    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20459            String authority) {
20460        if (app == null) return;
20461        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20462            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20463            if (userState == null) return;
20464            final long now = SystemClock.elapsedRealtime();
20465            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20466            if (lastReported == null || lastReported < now - 60 * 1000L) {
20467                mUsageStatsService.reportContentProviderUsage(
20468                        authority, providerPkgName, app.userId);
20469                userState.mProviderLastReportedFg.put(authority, now);
20470            }
20471        }
20472    }
20473
20474    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20475        if (DEBUG_USAGE_STATS) {
20476            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20477                    + "] state changes: old = " + app.setProcState + ", new = "
20478                    + app.curProcState);
20479        }
20480        if (mUsageStatsService == null) {
20481            return;
20482        }
20483        boolean isInteraction;
20484        // To avoid some abuse patterns, we are going to be careful about what we consider
20485        // to be an app interaction.  Being the top activity doesn't count while the display
20486        // is sleeping, nor do short foreground services.
20487        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20488            isInteraction = true;
20489            app.fgInteractionTime = 0;
20490        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20491            if (app.fgInteractionTime == 0) {
20492                app.fgInteractionTime = nowElapsed;
20493                isInteraction = false;
20494            } else {
20495                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20496            }
20497        } else {
20498            isInteraction = app.curProcState
20499                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20500            app.fgInteractionTime = 0;
20501        }
20502        if (isInteraction && (!app.reportedInteraction
20503                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20504            app.interactionEventTime = nowElapsed;
20505            String[] packages = app.getPackageList();
20506            if (packages != null) {
20507                for (int i = 0; i < packages.length; i++) {
20508                    mUsageStatsService.reportEvent(packages[i], app.userId,
20509                            UsageEvents.Event.SYSTEM_INTERACTION);
20510                }
20511            }
20512        }
20513        app.reportedInteraction = isInteraction;
20514        if (!isInteraction) {
20515            app.interactionEventTime = 0;
20516        }
20517    }
20518
20519    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20520        if (proc.thread != null) {
20521            if (proc.baseProcessTracker != null) {
20522                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20523            }
20524        }
20525    }
20526
20527    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20528            ProcessRecord TOP_APP, boolean doingAll, long now) {
20529        if (app.thread == null) {
20530            return false;
20531        }
20532
20533        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20534
20535        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20536    }
20537
20538    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20539            boolean oomAdj) {
20540        if (isForeground != proc.foregroundServices) {
20541            proc.foregroundServices = isForeground;
20542            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20543                    proc.info.uid);
20544            if (isForeground) {
20545                if (curProcs == null) {
20546                    curProcs = new ArrayList<ProcessRecord>();
20547                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20548                }
20549                if (!curProcs.contains(proc)) {
20550                    curProcs.add(proc);
20551                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20552                            proc.info.packageName, proc.info.uid);
20553                }
20554            } else {
20555                if (curProcs != null) {
20556                    if (curProcs.remove(proc)) {
20557                        mBatteryStatsService.noteEvent(
20558                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20559                                proc.info.packageName, proc.info.uid);
20560                        if (curProcs.size() <= 0) {
20561                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20562                        }
20563                    }
20564                }
20565            }
20566            if (oomAdj) {
20567                updateOomAdjLocked();
20568            }
20569        }
20570    }
20571
20572    private final ActivityRecord resumedAppLocked() {
20573        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20574        String pkg;
20575        int uid;
20576        if (act != null) {
20577            pkg = act.packageName;
20578            uid = act.info.applicationInfo.uid;
20579        } else {
20580            pkg = null;
20581            uid = -1;
20582        }
20583        // Has the UID or resumed package name changed?
20584        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20585                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20586            if (mCurResumedPackage != null) {
20587                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20588                        mCurResumedPackage, mCurResumedUid);
20589            }
20590            mCurResumedPackage = pkg;
20591            mCurResumedUid = uid;
20592            if (mCurResumedPackage != null) {
20593                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20594                        mCurResumedPackage, mCurResumedUid);
20595            }
20596        }
20597        return act;
20598    }
20599
20600    final boolean updateOomAdjLocked(ProcessRecord app) {
20601        final ActivityRecord TOP_ACT = resumedAppLocked();
20602        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20603        final boolean wasCached = app.cached;
20604
20605        mAdjSeq++;
20606
20607        // This is the desired cached adjusment we want to tell it to use.
20608        // If our app is currently cached, we know it, and that is it.  Otherwise,
20609        // we don't know it yet, and it needs to now be cached we will then
20610        // need to do a complete oom adj.
20611        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20612                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20613        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20614                SystemClock.uptimeMillis());
20615        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20616            // Changed to/from cached state, so apps after it in the LRU
20617            // list may also be changed.
20618            updateOomAdjLocked();
20619        }
20620        return success;
20621    }
20622
20623    final void updateOomAdjLocked() {
20624        final ActivityRecord TOP_ACT = resumedAppLocked();
20625        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20626        final long now = SystemClock.uptimeMillis();
20627        final long nowElapsed = SystemClock.elapsedRealtime();
20628        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20629        final int N = mLruProcesses.size();
20630
20631        if (false) {
20632            RuntimeException e = new RuntimeException();
20633            e.fillInStackTrace();
20634            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20635        }
20636
20637        // Reset state in all uid records.
20638        for (int i=mActiveUids.size()-1; i>=0; i--) {
20639            final UidRecord uidRec = mActiveUids.valueAt(i);
20640            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20641                    "Starting update of " + uidRec);
20642            uidRec.reset();
20643        }
20644
20645        mStackSupervisor.rankTaskLayersIfNeeded();
20646
20647        mAdjSeq++;
20648        mNewNumServiceProcs = 0;
20649        mNewNumAServiceProcs = 0;
20650
20651        final int emptyProcessLimit;
20652        final int cachedProcessLimit;
20653        if (mProcessLimit <= 0) {
20654            emptyProcessLimit = cachedProcessLimit = 0;
20655        } else if (mProcessLimit == 1) {
20656            emptyProcessLimit = 1;
20657            cachedProcessLimit = 0;
20658        } else {
20659            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20660            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20661        }
20662
20663        // Let's determine how many processes we have running vs.
20664        // how many slots we have for background processes; we may want
20665        // to put multiple processes in a slot of there are enough of
20666        // them.
20667        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20668                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20669        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20670        if (numEmptyProcs > cachedProcessLimit) {
20671            // If there are more empty processes than our limit on cached
20672            // processes, then use the cached process limit for the factor.
20673            // This ensures that the really old empty processes get pushed
20674            // down to the bottom, so if we are running low on memory we will
20675            // have a better chance at keeping around more cached processes
20676            // instead of a gazillion empty processes.
20677            numEmptyProcs = cachedProcessLimit;
20678        }
20679        int emptyFactor = numEmptyProcs/numSlots;
20680        if (emptyFactor < 1) emptyFactor = 1;
20681        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20682        if (cachedFactor < 1) cachedFactor = 1;
20683        int stepCached = 0;
20684        int stepEmpty = 0;
20685        int numCached = 0;
20686        int numEmpty = 0;
20687        int numTrimming = 0;
20688
20689        mNumNonCachedProcs = 0;
20690        mNumCachedHiddenProcs = 0;
20691
20692        // First update the OOM adjustment for each of the
20693        // application processes based on their current state.
20694        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20695        int nextCachedAdj = curCachedAdj+1;
20696        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20697        int nextEmptyAdj = curEmptyAdj+2;
20698        for (int i=N-1; i>=0; i--) {
20699            ProcessRecord app = mLruProcesses.get(i);
20700            if (!app.killedByAm && app.thread != null) {
20701                app.procStateChanged = false;
20702                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20703
20704                // If we haven't yet assigned the final cached adj
20705                // to the process, do that now.
20706                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20707                    switch (app.curProcState) {
20708                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20709                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20710                            // This process is a cached process holding activities...
20711                            // assign it the next cached value for that type, and then
20712                            // step that cached level.
20713                            app.curRawAdj = curCachedAdj;
20714                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20715                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20716                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20717                                    + ")");
20718                            if (curCachedAdj != nextCachedAdj) {
20719                                stepCached++;
20720                                if (stepCached >= cachedFactor) {
20721                                    stepCached = 0;
20722                                    curCachedAdj = nextCachedAdj;
20723                                    nextCachedAdj += 2;
20724                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20725                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20726                                    }
20727                                }
20728                            }
20729                            break;
20730                        default:
20731                            // For everything else, assign next empty cached process
20732                            // level and bump that up.  Note that this means that
20733                            // long-running services that have dropped down to the
20734                            // cached level will be treated as empty (since their process
20735                            // state is still as a service), which is what we want.
20736                            app.curRawAdj = curEmptyAdj;
20737                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20738                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20739                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20740                                    + ")");
20741                            if (curEmptyAdj != nextEmptyAdj) {
20742                                stepEmpty++;
20743                                if (stepEmpty >= emptyFactor) {
20744                                    stepEmpty = 0;
20745                                    curEmptyAdj = nextEmptyAdj;
20746                                    nextEmptyAdj += 2;
20747                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20748                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20749                                    }
20750                                }
20751                            }
20752                            break;
20753                    }
20754                }
20755
20756                applyOomAdjLocked(app, true, now, nowElapsed);
20757
20758                // Count the number of process types.
20759                switch (app.curProcState) {
20760                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20761                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20762                        mNumCachedHiddenProcs++;
20763                        numCached++;
20764                        if (numCached > cachedProcessLimit) {
20765                            app.kill("cached #" + numCached, true);
20766                        }
20767                        break;
20768                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20769                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20770                                && app.lastActivityTime < oldTime) {
20771                            app.kill("empty for "
20772                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20773                                    / 1000) + "s", true);
20774                        } else {
20775                            numEmpty++;
20776                            if (numEmpty > emptyProcessLimit) {
20777                                app.kill("empty #" + numEmpty, true);
20778                            }
20779                        }
20780                        break;
20781                    default:
20782                        mNumNonCachedProcs++;
20783                        break;
20784                }
20785
20786                if (app.isolated && app.services.size() <= 0) {
20787                    // If this is an isolated process, and there are no
20788                    // services running in it, then the process is no longer
20789                    // needed.  We agressively kill these because we can by
20790                    // definition not re-use the same process again, and it is
20791                    // good to avoid having whatever code was running in them
20792                    // left sitting around after no longer needed.
20793                    app.kill("isolated not needed", true);
20794                } else {
20795                    // Keeping this process, update its uid.
20796                    final UidRecord uidRec = app.uidRecord;
20797                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20798                        uidRec.curProcState = app.curProcState;
20799                    }
20800                }
20801
20802                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20803                        && !app.killedByAm) {
20804                    numTrimming++;
20805                }
20806            }
20807        }
20808
20809        mNumServiceProcs = mNewNumServiceProcs;
20810
20811        // Now determine the memory trimming level of background processes.
20812        // Unfortunately we need to start at the back of the list to do this
20813        // properly.  We only do this if the number of background apps we
20814        // are managing to keep around is less than half the maximum we desire;
20815        // if we are keeping a good number around, we'll let them use whatever
20816        // memory they want.
20817        final int numCachedAndEmpty = numCached + numEmpty;
20818        int memFactor;
20819        if (numCached <= ProcessList.TRIM_CACHED_APPS
20820                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20821            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20822                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20823            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20824                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20825            } else {
20826                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20827            }
20828        } else {
20829            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20830        }
20831        // We always allow the memory level to go up (better).  We only allow it to go
20832        // down if we are in a state where that is allowed, *and* the total number of processes
20833        // has gone down since last time.
20834        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20835                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20836                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20837        if (memFactor > mLastMemoryLevel) {
20838            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20839                memFactor = mLastMemoryLevel;
20840                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20841            }
20842        }
20843        if (memFactor != mLastMemoryLevel) {
20844            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20845        }
20846        mLastMemoryLevel = memFactor;
20847        mLastNumProcesses = mLruProcesses.size();
20848        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20849        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20850        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20851            if (mLowRamStartTime == 0) {
20852                mLowRamStartTime = now;
20853            }
20854            int step = 0;
20855            int fgTrimLevel;
20856            switch (memFactor) {
20857                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20858                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20859                    break;
20860                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20861                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20862                    break;
20863                default:
20864                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20865                    break;
20866            }
20867            int factor = numTrimming/3;
20868            int minFactor = 2;
20869            if (mHomeProcess != null) minFactor++;
20870            if (mPreviousProcess != null) minFactor++;
20871            if (factor < minFactor) factor = minFactor;
20872            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20873            for (int i=N-1; i>=0; i--) {
20874                ProcessRecord app = mLruProcesses.get(i);
20875                if (allChanged || app.procStateChanged) {
20876                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20877                    app.procStateChanged = false;
20878                }
20879                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20880                        && !app.killedByAm) {
20881                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20882                        try {
20883                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20884                                    "Trimming memory of " + app.processName + " to " + curLevel);
20885                            app.thread.scheduleTrimMemory(curLevel);
20886                        } catch (RemoteException e) {
20887                        }
20888                        if (false) {
20889                            // For now we won't do this; our memory trimming seems
20890                            // to be good enough at this point that destroying
20891                            // activities causes more harm than good.
20892                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20893                                    && app != mHomeProcess && app != mPreviousProcess) {
20894                                // Need to do this on its own message because the stack may not
20895                                // be in a consistent state at this point.
20896                                // For these apps we will also finish their activities
20897                                // to help them free memory.
20898                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20899                            }
20900                        }
20901                    }
20902                    app.trimMemoryLevel = curLevel;
20903                    step++;
20904                    if (step >= factor) {
20905                        step = 0;
20906                        switch (curLevel) {
20907                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20908                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20909                                break;
20910                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20911                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20912                                break;
20913                        }
20914                    }
20915                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20916                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20917                            && app.thread != null) {
20918                        try {
20919                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20920                                    "Trimming memory of heavy-weight " + app.processName
20921                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20922                            app.thread.scheduleTrimMemory(
20923                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20924                        } catch (RemoteException e) {
20925                        }
20926                    }
20927                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20928                } else {
20929                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20930                            || app.systemNoUi) && app.pendingUiClean) {
20931                        // If this application is now in the background and it
20932                        // had done UI, then give it the special trim level to
20933                        // have it free UI resources.
20934                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20935                        if (app.trimMemoryLevel < level && app.thread != null) {
20936                            try {
20937                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20938                                        "Trimming memory of bg-ui " + app.processName
20939                                        + " to " + level);
20940                                app.thread.scheduleTrimMemory(level);
20941                            } catch (RemoteException e) {
20942                            }
20943                        }
20944                        app.pendingUiClean = false;
20945                    }
20946                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20947                        try {
20948                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20949                                    "Trimming memory of fg " + app.processName
20950                                    + " to " + fgTrimLevel);
20951                            app.thread.scheduleTrimMemory(fgTrimLevel);
20952                        } catch (RemoteException e) {
20953                        }
20954                    }
20955                    app.trimMemoryLevel = fgTrimLevel;
20956                }
20957            }
20958        } else {
20959            if (mLowRamStartTime != 0) {
20960                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20961                mLowRamStartTime = 0;
20962            }
20963            for (int i=N-1; i>=0; i--) {
20964                ProcessRecord app = mLruProcesses.get(i);
20965                if (allChanged || app.procStateChanged) {
20966                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20967                    app.procStateChanged = false;
20968                }
20969                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20970                        || app.systemNoUi) && app.pendingUiClean) {
20971                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20972                            && app.thread != null) {
20973                        try {
20974                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20975                                    "Trimming memory of ui hidden " + app.processName
20976                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20977                            app.thread.scheduleTrimMemory(
20978                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20979                        } catch (RemoteException e) {
20980                        }
20981                    }
20982                    app.pendingUiClean = false;
20983                }
20984                app.trimMemoryLevel = 0;
20985            }
20986        }
20987
20988        if (mAlwaysFinishActivities) {
20989            // Need to do this on its own message because the stack may not
20990            // be in a consistent state at this point.
20991            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20992        }
20993
20994        if (allChanged) {
20995            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20996        }
20997
20998        // Update from any uid changes.
20999        for (int i=mActiveUids.size()-1; i>=0; i--) {
21000            final UidRecord uidRec = mActiveUids.valueAt(i);
21001            int uidChange = UidRecord.CHANGE_PROCSTATE;
21002            if (uidRec.setProcState != uidRec.curProcState) {
21003                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21004                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21005                        + " to " + uidRec.curProcState);
21006                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21007                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21008                        uidRec.lastBackgroundTime = nowElapsed;
21009                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21010                            // Note: the background settle time is in elapsed realtime, while
21011                            // the handler time base is uptime.  All this means is that we may
21012                            // stop background uids later than we had intended, but that only
21013                            // happens because the device was sleeping so we are okay anyway.
21014                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21015                        }
21016                    }
21017                } else {
21018                    if (uidRec.idle) {
21019                        uidChange = UidRecord.CHANGE_ACTIVE;
21020                        uidRec.idle = false;
21021                    }
21022                    uidRec.lastBackgroundTime = 0;
21023                }
21024                uidRec.setProcState = uidRec.curProcState;
21025                enqueueUidChangeLocked(uidRec, -1, uidChange);
21026                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21027            }
21028        }
21029
21030        if (mProcessStats.shouldWriteNowLocked(now)) {
21031            mHandler.post(new Runnable() {
21032                @Override public void run() {
21033                    synchronized (ActivityManagerService.this) {
21034                        mProcessStats.writeStateAsyncLocked();
21035                    }
21036                }
21037            });
21038        }
21039
21040        if (DEBUG_OOM_ADJ) {
21041            final long duration = SystemClock.uptimeMillis() - now;
21042            if (false) {
21043                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21044                        new RuntimeException("here").fillInStackTrace());
21045            } else {
21046                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21047            }
21048        }
21049    }
21050
21051    final void idleUids() {
21052        synchronized (this) {
21053            final long nowElapsed = SystemClock.elapsedRealtime();
21054            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21055            long nextTime = 0;
21056            for (int i=mActiveUids.size()-1; i>=0; i--) {
21057                final UidRecord uidRec = mActiveUids.valueAt(i);
21058                final long bgTime = uidRec.lastBackgroundTime;
21059                if (bgTime > 0 && !uidRec.idle) {
21060                    if (bgTime <= maxBgTime) {
21061                        uidRec.idle = true;
21062                        doStopUidLocked(uidRec.uid, uidRec);
21063                    } else {
21064                        if (nextTime == 0 || nextTime > bgTime) {
21065                            nextTime = bgTime;
21066                        }
21067                    }
21068                }
21069            }
21070            if (nextTime > 0) {
21071                mHandler.removeMessages(IDLE_UIDS_MSG);
21072                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21073                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21074            }
21075        }
21076    }
21077
21078    final void runInBackgroundDisabled(int uid) {
21079        synchronized (this) {
21080            UidRecord uidRec = mActiveUids.get(uid);
21081            if (uidRec != null) {
21082                // This uid is actually running...  should it be considered background now?
21083                if (uidRec.idle) {
21084                    doStopUidLocked(uidRec.uid, uidRec);
21085                }
21086            } else {
21087                // This uid isn't actually running...  still send a report about it being "stopped".
21088                doStopUidLocked(uid, null);
21089            }
21090        }
21091    }
21092
21093    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21094        mServices.stopInBackgroundLocked(uid);
21095        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21096    }
21097
21098    final void trimApplications() {
21099        synchronized (this) {
21100            int i;
21101
21102            // First remove any unused application processes whose package
21103            // has been removed.
21104            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21105                final ProcessRecord app = mRemovedProcesses.get(i);
21106                if (app.activities.size() == 0
21107                        && app.curReceiver == null && app.services.size() == 0) {
21108                    Slog.i(
21109                        TAG, "Exiting empty application process "
21110                        + app.toShortString() + " ("
21111                        + (app.thread != null ? app.thread.asBinder() : null)
21112                        + ")\n");
21113                    if (app.pid > 0 && app.pid != MY_PID) {
21114                        app.kill("empty", false);
21115                    } else {
21116                        try {
21117                            app.thread.scheduleExit();
21118                        } catch (Exception e) {
21119                            // Ignore exceptions.
21120                        }
21121                    }
21122                    cleanUpApplicationRecordLocked(app, false, true, -1);
21123                    mRemovedProcesses.remove(i);
21124
21125                    if (app.persistent) {
21126                        addAppLocked(app.info, false, null /* ABI override */);
21127                    }
21128                }
21129            }
21130
21131            // Now update the oom adj for all processes.
21132            updateOomAdjLocked();
21133        }
21134    }
21135
21136    /** This method sends the specified signal to each of the persistent apps */
21137    public void signalPersistentProcesses(int sig) throws RemoteException {
21138        if (sig != Process.SIGNAL_USR1) {
21139            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21140        }
21141
21142        synchronized (this) {
21143            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21144                    != PackageManager.PERMISSION_GRANTED) {
21145                throw new SecurityException("Requires permission "
21146                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21147            }
21148
21149            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21150                ProcessRecord r = mLruProcesses.get(i);
21151                if (r.thread != null && r.persistent) {
21152                    Process.sendSignal(r.pid, sig);
21153                }
21154            }
21155        }
21156    }
21157
21158    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21159        if (proc == null || proc == mProfileProc) {
21160            proc = mProfileProc;
21161            profileType = mProfileType;
21162            clearProfilerLocked();
21163        }
21164        if (proc == null) {
21165            return;
21166        }
21167        try {
21168            proc.thread.profilerControl(false, null, profileType);
21169        } catch (RemoteException e) {
21170            throw new IllegalStateException("Process disappeared");
21171        }
21172    }
21173
21174    private void clearProfilerLocked() {
21175        if (mProfileFd != null) {
21176            try {
21177                mProfileFd.close();
21178            } catch (IOException e) {
21179            }
21180        }
21181        mProfileApp = null;
21182        mProfileProc = null;
21183        mProfileFile = null;
21184        mProfileType = 0;
21185        mAutoStopProfiler = false;
21186        mSamplingInterval = 0;
21187    }
21188
21189    public boolean profileControl(String process, int userId, boolean start,
21190            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21191
21192        try {
21193            synchronized (this) {
21194                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21195                // its own permission.
21196                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21197                        != PackageManager.PERMISSION_GRANTED) {
21198                    throw new SecurityException("Requires permission "
21199                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21200                }
21201
21202                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21203                    throw new IllegalArgumentException("null profile info or fd");
21204                }
21205
21206                ProcessRecord proc = null;
21207                if (process != null) {
21208                    proc = findProcessLocked(process, userId, "profileControl");
21209                }
21210
21211                if (start && (proc == null || proc.thread == null)) {
21212                    throw new IllegalArgumentException("Unknown process: " + process);
21213                }
21214
21215                if (start) {
21216                    stopProfilerLocked(null, 0);
21217                    setProfileApp(proc.info, proc.processName, profilerInfo);
21218                    mProfileProc = proc;
21219                    mProfileType = profileType;
21220                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21221                    try {
21222                        fd = fd.dup();
21223                    } catch (IOException e) {
21224                        fd = null;
21225                    }
21226                    profilerInfo.profileFd = fd;
21227                    proc.thread.profilerControl(start, profilerInfo, profileType);
21228                    fd = null;
21229                    mProfileFd = null;
21230                } else {
21231                    stopProfilerLocked(proc, profileType);
21232                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21233                        try {
21234                            profilerInfo.profileFd.close();
21235                        } catch (IOException e) {
21236                        }
21237                    }
21238                }
21239
21240                return true;
21241            }
21242        } catch (RemoteException e) {
21243            throw new IllegalStateException("Process disappeared");
21244        } finally {
21245            if (profilerInfo != null && profilerInfo.profileFd != null) {
21246                try {
21247                    profilerInfo.profileFd.close();
21248                } catch (IOException e) {
21249                }
21250            }
21251        }
21252    }
21253
21254    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21255        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21256                userId, true, ALLOW_FULL_ONLY, callName, null);
21257        ProcessRecord proc = null;
21258        try {
21259            int pid = Integer.parseInt(process);
21260            synchronized (mPidsSelfLocked) {
21261                proc = mPidsSelfLocked.get(pid);
21262            }
21263        } catch (NumberFormatException e) {
21264        }
21265
21266        if (proc == null) {
21267            ArrayMap<String, SparseArray<ProcessRecord>> all
21268                    = mProcessNames.getMap();
21269            SparseArray<ProcessRecord> procs = all.get(process);
21270            if (procs != null && procs.size() > 0) {
21271                proc = procs.valueAt(0);
21272                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21273                    for (int i=1; i<procs.size(); i++) {
21274                        ProcessRecord thisProc = procs.valueAt(i);
21275                        if (thisProc.userId == userId) {
21276                            proc = thisProc;
21277                            break;
21278                        }
21279                    }
21280                }
21281            }
21282        }
21283
21284        return proc;
21285    }
21286
21287    public boolean dumpHeap(String process, int userId, boolean managed,
21288            String path, ParcelFileDescriptor fd) throws RemoteException {
21289
21290        try {
21291            synchronized (this) {
21292                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21293                // its own permission (same as profileControl).
21294                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21295                        != PackageManager.PERMISSION_GRANTED) {
21296                    throw new SecurityException("Requires permission "
21297                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21298                }
21299
21300                if (fd == null) {
21301                    throw new IllegalArgumentException("null fd");
21302                }
21303
21304                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21305                if (proc == null || proc.thread == null) {
21306                    throw new IllegalArgumentException("Unknown process: " + process);
21307                }
21308
21309                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21310                if (!isDebuggable) {
21311                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21312                        throw new SecurityException("Process not debuggable: " + proc);
21313                    }
21314                }
21315
21316                proc.thread.dumpHeap(managed, path, fd);
21317                fd = null;
21318                return true;
21319            }
21320        } catch (RemoteException e) {
21321            throw new IllegalStateException("Process disappeared");
21322        } finally {
21323            if (fd != null) {
21324                try {
21325                    fd.close();
21326                } catch (IOException e) {
21327                }
21328            }
21329        }
21330    }
21331
21332    @Override
21333    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21334            String reportPackage) {
21335        if (processName != null) {
21336            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21337                    "setDumpHeapDebugLimit()");
21338        } else {
21339            synchronized (mPidsSelfLocked) {
21340                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21341                if (proc == null) {
21342                    throw new SecurityException("No process found for calling pid "
21343                            + Binder.getCallingPid());
21344                }
21345                if (!Build.IS_DEBUGGABLE
21346                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21347                    throw new SecurityException("Not running a debuggable build");
21348                }
21349                processName = proc.processName;
21350                uid = proc.uid;
21351                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21352                    throw new SecurityException("Package " + reportPackage + " is not running in "
21353                            + proc);
21354                }
21355            }
21356        }
21357        synchronized (this) {
21358            if (maxMemSize > 0) {
21359                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21360            } else {
21361                if (uid != 0) {
21362                    mMemWatchProcesses.remove(processName, uid);
21363                } else {
21364                    mMemWatchProcesses.getMap().remove(processName);
21365                }
21366            }
21367        }
21368    }
21369
21370    @Override
21371    public void dumpHeapFinished(String path) {
21372        synchronized (this) {
21373            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21374                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21375                        + " does not match last pid " + mMemWatchDumpPid);
21376                return;
21377            }
21378            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21379                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21380                        + " does not match last path " + mMemWatchDumpFile);
21381                return;
21382            }
21383            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21384            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21385        }
21386    }
21387
21388    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21389    public void monitor() {
21390        synchronized (this) { }
21391    }
21392
21393    void onCoreSettingsChange(Bundle settings) {
21394        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21395            ProcessRecord processRecord = mLruProcesses.get(i);
21396            try {
21397                if (processRecord.thread != null) {
21398                    processRecord.thread.setCoreSettings(settings);
21399                }
21400            } catch (RemoteException re) {
21401                /* ignore */
21402            }
21403        }
21404    }
21405
21406    // Multi-user methods
21407
21408    /**
21409     * Start user, if its not already running, but don't bring it to foreground.
21410     */
21411    @Override
21412    public boolean startUserInBackground(final int userId) {
21413        return mUserController.startUser(userId, /* foreground */ false);
21414    }
21415
21416    @Override
21417    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21418        return mUserController.unlockUser(userId, token, secret, listener);
21419    }
21420
21421    @Override
21422    public boolean switchUser(final int targetUserId) {
21423        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21424        UserInfo currentUserInfo;
21425        UserInfo targetUserInfo;
21426        synchronized (this) {
21427            int currentUserId = mUserController.getCurrentUserIdLocked();
21428            currentUserInfo = mUserController.getUserInfo(currentUserId);
21429            targetUserInfo = mUserController.getUserInfo(targetUserId);
21430            if (targetUserInfo == null) {
21431                Slog.w(TAG, "No user info for user #" + targetUserId);
21432                return false;
21433            }
21434            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21435                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21436                        + " when device is in demo mode");
21437                return false;
21438            }
21439            if (!targetUserInfo.supportsSwitchTo()) {
21440                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21441                return false;
21442            }
21443            if (targetUserInfo.isManagedProfile()) {
21444                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21445                return false;
21446            }
21447            mUserController.setTargetUserIdLocked(targetUserId);
21448        }
21449        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21450        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21451        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21452        return true;
21453    }
21454
21455    void scheduleStartProfilesLocked() {
21456        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21457            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21458                    DateUtils.SECOND_IN_MILLIS);
21459        }
21460    }
21461
21462    @Override
21463    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21464        return mUserController.stopUser(userId, force, callback);
21465    }
21466
21467    @Override
21468    public UserInfo getCurrentUser() {
21469        return mUserController.getCurrentUser();
21470    }
21471
21472    @Override
21473    public boolean isUserRunning(int userId, int flags) {
21474        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21475                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21476            String msg = "Permission Denial: isUserRunning() from pid="
21477                    + Binder.getCallingPid()
21478                    + ", uid=" + Binder.getCallingUid()
21479                    + " requires " + INTERACT_ACROSS_USERS;
21480            Slog.w(TAG, msg);
21481            throw new SecurityException(msg);
21482        }
21483        synchronized (this) {
21484            return mUserController.isUserRunningLocked(userId, flags);
21485        }
21486    }
21487
21488    @Override
21489    public int[] getRunningUserIds() {
21490        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21491                != PackageManager.PERMISSION_GRANTED) {
21492            String msg = "Permission Denial: isUserRunning() from pid="
21493                    + Binder.getCallingPid()
21494                    + ", uid=" + Binder.getCallingUid()
21495                    + " requires " + INTERACT_ACROSS_USERS;
21496            Slog.w(TAG, msg);
21497            throw new SecurityException(msg);
21498        }
21499        synchronized (this) {
21500            return mUserController.getStartedUserArrayLocked();
21501        }
21502    }
21503
21504    @Override
21505    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21506        mUserController.registerUserSwitchObserver(observer, name);
21507    }
21508
21509    @Override
21510    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21511        mUserController.unregisterUserSwitchObserver(observer);
21512    }
21513
21514    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21515        if (info == null) return null;
21516        ApplicationInfo newInfo = new ApplicationInfo(info);
21517        newInfo.initForUser(userId);
21518        return newInfo;
21519    }
21520
21521    public boolean isUserStopped(int userId) {
21522        synchronized (this) {
21523            return mUserController.getStartedUserStateLocked(userId) == null;
21524        }
21525    }
21526
21527    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21528        if (aInfo == null
21529                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21530            return aInfo;
21531        }
21532
21533        ActivityInfo info = new ActivityInfo(aInfo);
21534        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21535        return info;
21536    }
21537
21538    private boolean processSanityChecksLocked(ProcessRecord process) {
21539        if (process == null || process.thread == null) {
21540            return false;
21541        }
21542
21543        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21544        if (!isDebuggable) {
21545            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21546                return false;
21547            }
21548        }
21549
21550        return true;
21551    }
21552
21553    public boolean startBinderTracking() throws RemoteException {
21554        synchronized (this) {
21555            mBinderTransactionTrackingEnabled = true;
21556            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21557            // permission (same as profileControl).
21558            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21559                    != PackageManager.PERMISSION_GRANTED) {
21560                throw new SecurityException("Requires permission "
21561                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21562            }
21563
21564            for (int i = 0; i < mLruProcesses.size(); i++) {
21565                ProcessRecord process = mLruProcesses.get(i);
21566                if (!processSanityChecksLocked(process)) {
21567                    continue;
21568                }
21569                try {
21570                    process.thread.startBinderTracking();
21571                } catch (RemoteException e) {
21572                    Log.v(TAG, "Process disappared");
21573                }
21574            }
21575            return true;
21576        }
21577    }
21578
21579    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21580        try {
21581            synchronized (this) {
21582                mBinderTransactionTrackingEnabled = false;
21583                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21584                // permission (same as profileControl).
21585                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21586                        != PackageManager.PERMISSION_GRANTED) {
21587                    throw new SecurityException("Requires permission "
21588                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21589                }
21590
21591                if (fd == null) {
21592                    throw new IllegalArgumentException("null fd");
21593                }
21594
21595                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21596                pw.println("Binder transaction traces for all processes.\n");
21597                for (ProcessRecord process : mLruProcesses) {
21598                    if (!processSanityChecksLocked(process)) {
21599                        continue;
21600                    }
21601
21602                    pw.println("Traces for process: " + process.processName);
21603                    pw.flush();
21604                    try {
21605                        TransferPipe tp = new TransferPipe();
21606                        try {
21607                            process.thread.stopBinderTrackingAndDump(
21608                                    tp.getWriteFd().getFileDescriptor());
21609                            tp.go(fd.getFileDescriptor());
21610                        } finally {
21611                            tp.kill();
21612                        }
21613                    } catch (IOException e) {
21614                        pw.println("Failure while dumping IPC traces from " + process +
21615                                ".  Exception: " + e);
21616                        pw.flush();
21617                    } catch (RemoteException e) {
21618                        pw.println("Got a RemoteException while dumping IPC traces from " +
21619                                process + ".  Exception: " + e);
21620                        pw.flush();
21621                    }
21622                }
21623                fd = null;
21624                return true;
21625            }
21626        } finally {
21627            if (fd != null) {
21628                try {
21629                    fd.close();
21630                } catch (IOException e) {
21631                }
21632            }
21633        }
21634    }
21635
21636    private final class LocalService extends ActivityManagerInternal {
21637        @Override
21638        public void onWakefulnessChanged(int wakefulness) {
21639            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21640        }
21641
21642        @Override
21643        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21644                String processName, String abiOverride, int uid, Runnable crashHandler) {
21645            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21646                    processName, abiOverride, uid, crashHandler);
21647        }
21648
21649        @Override
21650        public SleepToken acquireSleepToken(String tag) {
21651            Preconditions.checkNotNull(tag);
21652
21653            ComponentName requestedVrService = null;
21654            ComponentName callingVrActivity = null;
21655            int userId = -1;
21656            synchronized (ActivityManagerService.this) {
21657                if (mFocusedActivity != null) {
21658                    requestedVrService = mFocusedActivity.requestedVrComponent;
21659                    callingVrActivity = mFocusedActivity.info.getComponentName();
21660                    userId = mFocusedActivity.userId;
21661                }
21662            }
21663
21664            if (requestedVrService != null) {
21665                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21666            }
21667
21668            synchronized (ActivityManagerService.this) {
21669                SleepTokenImpl token = new SleepTokenImpl(tag);
21670                mSleepTokens.add(token);
21671                updateSleepIfNeededLocked();
21672                return token;
21673            }
21674        }
21675
21676        @Override
21677        public ComponentName getHomeActivityForUser(int userId) {
21678            synchronized (ActivityManagerService.this) {
21679                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21680                return homeActivity == null ? null : homeActivity.realActivity;
21681            }
21682        }
21683
21684        @Override
21685        public void onUserRemoved(int userId) {
21686            synchronized (ActivityManagerService.this) {
21687                ActivityManagerService.this.onUserStoppedLocked(userId);
21688            }
21689        }
21690
21691        @Override
21692        public void onLocalVoiceInteractionStarted(IBinder activity,
21693                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21694            synchronized (ActivityManagerService.this) {
21695                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21696                        voiceSession, voiceInteractor);
21697            }
21698        }
21699
21700        @Override
21701        public void notifyStartingWindowDrawn() {
21702            synchronized (ActivityManagerService.this) {
21703                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21704            }
21705        }
21706
21707        @Override
21708        public void notifyAppTransitionStarting(int reason) {
21709            synchronized (ActivityManagerService.this) {
21710                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21711            }
21712        }
21713
21714        @Override
21715        public void notifyAppTransitionFinished() {
21716            synchronized (ActivityManagerService.this) {
21717                mStackSupervisor.notifyAppTransitionDone();
21718            }
21719        }
21720
21721        @Override
21722        public void notifyAppTransitionCancelled() {
21723            synchronized (ActivityManagerService.this) {
21724                mStackSupervisor.notifyAppTransitionDone();
21725            }
21726        }
21727
21728        @Override
21729        public List<IBinder> getTopVisibleActivities() {
21730            synchronized (ActivityManagerService.this) {
21731                return mStackSupervisor.getTopVisibleActivities();
21732            }
21733        }
21734
21735        @Override
21736        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21737            synchronized (ActivityManagerService.this) {
21738                mStackSupervisor.setDockedStackMinimized(minimized);
21739            }
21740        }
21741
21742        @Override
21743        public void killForegroundAppsForUser(int userHandle) {
21744            synchronized (ActivityManagerService.this) {
21745                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21746                final int NP = mProcessNames.getMap().size();
21747                for (int ip = 0; ip < NP; ip++) {
21748                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21749                    final int NA = apps.size();
21750                    for (int ia = 0; ia < NA; ia++) {
21751                        final ProcessRecord app = apps.valueAt(ia);
21752                        if (app.persistent) {
21753                            // We don't kill persistent processes.
21754                            continue;
21755                        }
21756                        if (app.removed) {
21757                            procs.add(app);
21758                        } else if (app.userId == userHandle && app.foregroundActivities) {
21759                            app.removed = true;
21760                            procs.add(app);
21761                        }
21762                    }
21763                }
21764
21765                final int N = procs.size();
21766                for (int i = 0; i < N; i++) {
21767                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21768                }
21769            }
21770        }
21771
21772        @Override
21773        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21774            if (!(target instanceof PendingIntentRecord)) {
21775                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21776                return;
21777            }
21778            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21779        }
21780
21781        @Override
21782        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21783                int userId) {
21784            Preconditions.checkNotNull(values, "Configuration must not be null");
21785            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21786            synchronized (ActivityManagerService.this) {
21787                updateConfigurationLocked(values, null, false, true, userId);
21788            }
21789        }
21790
21791        @Override
21792        public IIntentSender getActivityIntentSenderAsPackage(
21793                String packageName, int userId, int requestCode, Intent intent,
21794                int flags, Bundle bOptions) {
21795            String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
21796                    mContext.getContentResolver()) : null;
21797
21798            // UID of the package on user userId.
21799            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21800            // packageUid may not be initialized.
21801            int packageUid = 0;
21802            try {
21803                packageUid = AppGlobals.getPackageManager().getPackageUid(
21804                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21805            } catch (RemoteException e) {
21806                // Shouldn't happen.
21807            }
21808
21809            synchronized (ActivityManagerService.this) {
21810                return getIntentSenderLocked(
21811                        ActivityManager.INTENT_SENDER_ACTIVITY, packageName, packageUid,
21812                        UserHandle.getUserId(packageUid), /*token*/ null, /*resultWho*/ null,
21813                        requestCode, new Intent[] {intent}, new String[]{resolvedType},
21814                        flags, bOptions);
21815            }
21816        }
21817    }
21818
21819    private final class SleepTokenImpl extends SleepToken {
21820        private final String mTag;
21821        private final long mAcquireTime;
21822
21823        public SleepTokenImpl(String tag) {
21824            mTag = tag;
21825            mAcquireTime = SystemClock.uptimeMillis();
21826        }
21827
21828        @Override
21829        public void release() {
21830            synchronized (ActivityManagerService.this) {
21831                if (mSleepTokens.remove(this)) {
21832                    updateSleepIfNeededLocked();
21833                }
21834            }
21835        }
21836
21837        @Override
21838        public String toString() {
21839            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21840        }
21841    }
21842
21843    /**
21844     * An implementation of IAppTask, that allows an app to manage its own tasks via
21845     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21846     * only the process that calls getAppTasks() can call the AppTask methods.
21847     */
21848    class AppTaskImpl extends IAppTask.Stub {
21849        private int mTaskId;
21850        private int mCallingUid;
21851
21852        public AppTaskImpl(int taskId, int callingUid) {
21853            mTaskId = taskId;
21854            mCallingUid = callingUid;
21855        }
21856
21857        private void checkCaller() {
21858            if (mCallingUid != Binder.getCallingUid()) {
21859                throw new SecurityException("Caller " + mCallingUid
21860                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21861            }
21862        }
21863
21864        @Override
21865        public void finishAndRemoveTask() {
21866            checkCaller();
21867
21868            synchronized (ActivityManagerService.this) {
21869                long origId = Binder.clearCallingIdentity();
21870                try {
21871                    // We remove the task from recents to preserve backwards
21872                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21873                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21874                    }
21875                } finally {
21876                    Binder.restoreCallingIdentity(origId);
21877                }
21878            }
21879        }
21880
21881        @Override
21882        public ActivityManager.RecentTaskInfo getTaskInfo() {
21883            checkCaller();
21884
21885            synchronized (ActivityManagerService.this) {
21886                long origId = Binder.clearCallingIdentity();
21887                try {
21888                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21889                    if (tr == null) {
21890                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21891                    }
21892                    return createRecentTaskInfoFromTaskRecord(tr);
21893                } finally {
21894                    Binder.restoreCallingIdentity(origId);
21895                }
21896            }
21897        }
21898
21899        @Override
21900        public void moveToFront() {
21901            checkCaller();
21902            // Will bring task to front if it already has a root activity.
21903            final long origId = Binder.clearCallingIdentity();
21904            try {
21905                synchronized (this) {
21906                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21907                }
21908            } finally {
21909                Binder.restoreCallingIdentity(origId);
21910            }
21911        }
21912
21913        @Override
21914        public int startActivity(IBinder whoThread, String callingPackage,
21915                Intent intent, String resolvedType, Bundle bOptions) {
21916            checkCaller();
21917
21918            int callingUser = UserHandle.getCallingUserId();
21919            TaskRecord tr;
21920            IApplicationThread appThread;
21921            synchronized (ActivityManagerService.this) {
21922                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21923                if (tr == null) {
21924                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21925                }
21926                appThread = ApplicationThreadNative.asInterface(whoThread);
21927                if (appThread == null) {
21928                    throw new IllegalArgumentException("Bad app thread " + appThread);
21929                }
21930            }
21931            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21932                    resolvedType, null, null, null, null, 0, 0, null, null,
21933                    null, bOptions, false, callingUser, null, tr);
21934        }
21935
21936        @Override
21937        public void setExcludeFromRecents(boolean exclude) {
21938            checkCaller();
21939
21940            synchronized (ActivityManagerService.this) {
21941                long origId = Binder.clearCallingIdentity();
21942                try {
21943                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21944                    if (tr == null) {
21945                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21946                    }
21947                    Intent intent = tr.getBaseIntent();
21948                    if (exclude) {
21949                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21950                    } else {
21951                        intent.setFlags(intent.getFlags()
21952                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21953                    }
21954                } finally {
21955                    Binder.restoreCallingIdentity(origId);
21956                }
21957            }
21958        }
21959    }
21960
21961    /**
21962     * Kill processes for the user with id userId and that depend on the package named packageName
21963     */
21964    @Override
21965    public void killPackageDependents(String packageName, int userId) {
21966        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21967        if (packageName == null) {
21968            throw new NullPointerException(
21969                    "Cannot kill the dependents of a package without its name.");
21970        }
21971
21972        long callingId = Binder.clearCallingIdentity();
21973        IPackageManager pm = AppGlobals.getPackageManager();
21974        int pkgUid = -1;
21975        try {
21976            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21977        } catch (RemoteException e) {
21978        }
21979        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21980            throw new IllegalArgumentException(
21981                    "Cannot kill dependents of non-existing package " + packageName);
21982        }
21983        try {
21984            synchronized(this) {
21985                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21986                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21987                        "dep: " + packageName);
21988            }
21989        } finally {
21990            Binder.restoreCallingIdentity(callingId);
21991        }
21992    }
21993}
21994