ActivityManagerService.java revision db3e4ecf86939924be863e95d1db9fbb328fa9d8
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            throw new SecurityException();
6672        }
6673        mWindowManager.showBootMessage(msg, always);
6674    }
6675
6676    @Override
6677    public void keyguardWaitingForActivityDrawn() {
6678        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6679        final long token = Binder.clearCallingIdentity();
6680        try {
6681            synchronized (this) {
6682                if (DEBUG_LOCKSCREEN) logLockScreen("");
6683                mWindowManager.keyguardWaitingForActivityDrawn();
6684                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6685                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6686                    updateSleepIfNeededLocked();
6687                }
6688            }
6689        } finally {
6690            Binder.restoreCallingIdentity(token);
6691        }
6692    }
6693
6694    @Override
6695    public void keyguardGoingAway(int flags) {
6696        enforceNotIsolatedCaller("keyguardGoingAway");
6697        final long token = Binder.clearCallingIdentity();
6698        try {
6699            synchronized (this) {
6700                if (DEBUG_LOCKSCREEN) logLockScreen("");
6701                mWindowManager.keyguardGoingAway(flags);
6702                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6703                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6704                    updateSleepIfNeededLocked();
6705
6706                    // Some stack visibility might change (e.g. docked stack)
6707                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6708                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6709                }
6710            }
6711        } finally {
6712            Binder.restoreCallingIdentity(token);
6713        }
6714    }
6715
6716    final void finishBooting() {
6717        synchronized (this) {
6718            if (!mBootAnimationComplete) {
6719                mCallFinishBooting = true;
6720                return;
6721            }
6722            mCallFinishBooting = false;
6723        }
6724
6725        ArraySet<String> completedIsas = new ArraySet<String>();
6726        for (String abi : Build.SUPPORTED_ABIS) {
6727            Process.establishZygoteConnectionForAbi(abi);
6728            final String instructionSet = VMRuntime.getInstructionSet(abi);
6729            if (!completedIsas.contains(instructionSet)) {
6730                try {
6731                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6732                } catch (InstallerException e) {
6733                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6734                            e.getMessage() +")");
6735                }
6736                completedIsas.add(instructionSet);
6737            }
6738        }
6739
6740        IntentFilter pkgFilter = new IntentFilter();
6741        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6742        pkgFilter.addDataScheme("package");
6743        mContext.registerReceiver(new BroadcastReceiver() {
6744            @Override
6745            public void onReceive(Context context, Intent intent) {
6746                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6747                if (pkgs != null) {
6748                    for (String pkg : pkgs) {
6749                        synchronized (ActivityManagerService.this) {
6750                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6751                                    0, "query restart")) {
6752                                setResultCode(Activity.RESULT_OK);
6753                                return;
6754                            }
6755                        }
6756                    }
6757                }
6758            }
6759        }, pkgFilter);
6760
6761        IntentFilter dumpheapFilter = new IntentFilter();
6762        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6763        mContext.registerReceiver(new BroadcastReceiver() {
6764            @Override
6765            public void onReceive(Context context, Intent intent) {
6766                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6767                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6768                } else {
6769                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6770                }
6771            }
6772        }, dumpheapFilter);
6773
6774        // Let system services know.
6775        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6776
6777        synchronized (this) {
6778            // Ensure that any processes we had put on hold are now started
6779            // up.
6780            final int NP = mProcessesOnHold.size();
6781            if (NP > 0) {
6782                ArrayList<ProcessRecord> procs =
6783                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6784                for (int ip=0; ip<NP; ip++) {
6785                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6786                            + procs.get(ip));
6787                    startProcessLocked(procs.get(ip), "on-hold", null);
6788                }
6789            }
6790
6791            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6792                // Start looking for apps that are abusing wake locks.
6793                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6794                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6795                // Tell anyone interested that we are done booting!
6796                SystemProperties.set("sys.boot_completed", "1");
6797
6798                // And trigger dev.bootcomplete if we are not showing encryption progress
6799                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6800                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6801                    SystemProperties.set("dev.bootcomplete", "1");
6802                }
6803                mUserController.sendBootCompletedLocked(
6804                        new IIntentReceiver.Stub() {
6805                            @Override
6806                            public void performReceive(Intent intent, int resultCode,
6807                                    String data, Bundle extras, boolean ordered,
6808                                    boolean sticky, int sendingUser) {
6809                                synchronized (ActivityManagerService.this) {
6810                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6811                                            true, false);
6812                                }
6813                            }
6814                        });
6815                scheduleStartProfilesLocked();
6816            }
6817        }
6818    }
6819
6820    @Override
6821    public void bootAnimationComplete() {
6822        final boolean callFinishBooting;
6823        synchronized (this) {
6824            callFinishBooting = mCallFinishBooting;
6825            mBootAnimationComplete = true;
6826        }
6827        if (callFinishBooting) {
6828            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6829            finishBooting();
6830            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6831        }
6832    }
6833
6834    final void ensureBootCompleted() {
6835        boolean booting;
6836        boolean enableScreen;
6837        synchronized (this) {
6838            booting = mBooting;
6839            mBooting = false;
6840            enableScreen = !mBooted;
6841            mBooted = true;
6842        }
6843
6844        if (booting) {
6845            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6846            finishBooting();
6847            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6848        }
6849
6850        if (enableScreen) {
6851            enableScreenAfterBoot();
6852        }
6853    }
6854
6855    @Override
6856    public final void activityResumed(IBinder token) {
6857        final long origId = Binder.clearCallingIdentity();
6858        synchronized(this) {
6859            ActivityStack stack = ActivityRecord.getStackLocked(token);
6860            if (stack != null) {
6861                stack.activityResumedLocked(token);
6862            }
6863        }
6864        Binder.restoreCallingIdentity(origId);
6865    }
6866
6867    @Override
6868    public final void activityPaused(IBinder token) {
6869        final long origId = Binder.clearCallingIdentity();
6870        synchronized(this) {
6871            ActivityStack stack = ActivityRecord.getStackLocked(token);
6872            if (stack != null) {
6873                stack.activityPausedLocked(token, false);
6874            }
6875        }
6876        Binder.restoreCallingIdentity(origId);
6877    }
6878
6879    @Override
6880    public final void activityStopped(IBinder token, Bundle icicle,
6881            PersistableBundle persistentState, CharSequence description) {
6882        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6883
6884        // Refuse possible leaked file descriptors
6885        if (icicle != null && icicle.hasFileDescriptors()) {
6886            throw new IllegalArgumentException("File descriptors passed in Bundle");
6887        }
6888
6889        final long origId = Binder.clearCallingIdentity();
6890
6891        synchronized (this) {
6892            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6893            if (r != null) {
6894                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6895            }
6896        }
6897
6898        trimApplications();
6899
6900        Binder.restoreCallingIdentity(origId);
6901    }
6902
6903    @Override
6904    public final void activityDestroyed(IBinder token) {
6905        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6906        synchronized (this) {
6907            ActivityStack stack = ActivityRecord.getStackLocked(token);
6908            if (stack != null) {
6909                stack.activityDestroyedLocked(token, "activityDestroyed");
6910            }
6911        }
6912    }
6913
6914    @Override
6915    public final void activityRelaunched(IBinder token) {
6916        final long origId = Binder.clearCallingIdentity();
6917        synchronized (this) {
6918            mStackSupervisor.activityRelaunchedLocked(token);
6919        }
6920        Binder.restoreCallingIdentity(origId);
6921    }
6922
6923    @Override
6924    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6925            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6926        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6927                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6928        synchronized (this) {
6929            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6930            if (record == null) {
6931                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6932                        + "found for: " + token);
6933            }
6934            record.setSizeConfigurations(horizontalSizeConfiguration,
6935                    verticalSizeConfigurations, smallestSizeConfigurations);
6936        }
6937    }
6938
6939    @Override
6940    public final void backgroundResourcesReleased(IBinder token) {
6941        final long origId = Binder.clearCallingIdentity();
6942        try {
6943            synchronized (this) {
6944                ActivityStack stack = ActivityRecord.getStackLocked(token);
6945                if (stack != null) {
6946                    stack.backgroundResourcesReleased();
6947                }
6948            }
6949        } finally {
6950            Binder.restoreCallingIdentity(origId);
6951        }
6952    }
6953
6954    @Override
6955    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6956        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6957    }
6958
6959    @Override
6960    public final void notifyEnterAnimationComplete(IBinder token) {
6961        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6962    }
6963
6964    @Override
6965    public String getCallingPackage(IBinder token) {
6966        synchronized (this) {
6967            ActivityRecord r = getCallingRecordLocked(token);
6968            return r != null ? r.info.packageName : null;
6969        }
6970    }
6971
6972    @Override
6973    public ComponentName getCallingActivity(IBinder token) {
6974        synchronized (this) {
6975            ActivityRecord r = getCallingRecordLocked(token);
6976            return r != null ? r.intent.getComponent() : null;
6977        }
6978    }
6979
6980    private ActivityRecord getCallingRecordLocked(IBinder token) {
6981        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6982        if (r == null) {
6983            return null;
6984        }
6985        return r.resultTo;
6986    }
6987
6988    @Override
6989    public ComponentName getActivityClassForToken(IBinder token) {
6990        synchronized(this) {
6991            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6992            if (r == null) {
6993                return null;
6994            }
6995            return r.intent.getComponent();
6996        }
6997    }
6998
6999    @Override
7000    public String getPackageForToken(IBinder token) {
7001        synchronized(this) {
7002            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7003            if (r == null) {
7004                return null;
7005            }
7006            return r.packageName;
7007        }
7008    }
7009
7010    @Override
7011    public boolean isRootVoiceInteraction(IBinder token) {
7012        synchronized(this) {
7013            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7014            if (r == null) {
7015                return false;
7016            }
7017            return r.rootVoiceInteraction;
7018        }
7019    }
7020
7021    @Override
7022    public IIntentSender getIntentSender(int type,
7023            String packageName, IBinder token, String resultWho,
7024            int requestCode, Intent[] intents, String[] resolvedTypes,
7025            int flags, Bundle bOptions, int userId) {
7026        enforceNotIsolatedCaller("getIntentSender");
7027        // Refuse possible leaked file descriptors
7028        if (intents != null) {
7029            if (intents.length < 1) {
7030                throw new IllegalArgumentException("Intents array length must be >= 1");
7031            }
7032            for (int i=0; i<intents.length; i++) {
7033                Intent intent = intents[i];
7034                if (intent != null) {
7035                    if (intent.hasFileDescriptors()) {
7036                        throw new IllegalArgumentException("File descriptors passed in Intent");
7037                    }
7038                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7039                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7040                        throw new IllegalArgumentException(
7041                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7042                    }
7043                    intents[i] = new Intent(intent);
7044                }
7045            }
7046            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7047                throw new IllegalArgumentException(
7048                        "Intent array length does not match resolvedTypes length");
7049            }
7050        }
7051        if (bOptions != null) {
7052            if (bOptions.hasFileDescriptors()) {
7053                throw new IllegalArgumentException("File descriptors passed in options");
7054            }
7055        }
7056
7057        synchronized(this) {
7058            int callingUid = Binder.getCallingUid();
7059            int origUserId = userId;
7060            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7061                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7062                    ALLOW_NON_FULL, "getIntentSender", null);
7063            if (origUserId == UserHandle.USER_CURRENT) {
7064                // We don't want to evaluate this until the pending intent is
7065                // actually executed.  However, we do want to always do the
7066                // security checking for it above.
7067                userId = UserHandle.USER_CURRENT;
7068            }
7069            try {
7070                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7071                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7072                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7073                    if (!UserHandle.isSameApp(callingUid, uid)) {
7074                        String msg = "Permission Denial: getIntentSender() from pid="
7075                            + Binder.getCallingPid()
7076                            + ", uid=" + Binder.getCallingUid()
7077                            + ", (need uid=" + uid + ")"
7078                            + " is not allowed to send as package " + packageName;
7079                        Slog.w(TAG, msg);
7080                        throw new SecurityException(msg);
7081                    }
7082                }
7083
7084                return getIntentSenderLocked(type, packageName, callingUid, userId,
7085                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7086
7087            } catch (RemoteException e) {
7088                throw new SecurityException(e);
7089            }
7090        }
7091    }
7092
7093    IIntentSender getIntentSenderLocked(int type, String packageName,
7094            int callingUid, int userId, IBinder token, String resultWho,
7095            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7096            Bundle bOptions) {
7097        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7098        ActivityRecord activity = null;
7099        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7100            activity = ActivityRecord.isInStackLocked(token);
7101            if (activity == null) {
7102                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7103                return null;
7104            }
7105            if (activity.finishing) {
7106                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7107                return null;
7108            }
7109        }
7110
7111        // We're going to be splicing together extras before sending, so we're
7112        // okay poking into any contained extras.
7113        if (intents != null) {
7114            for (int i = 0; i < intents.length; i++) {
7115                intents[i].setDefusable(true);
7116            }
7117        }
7118        Bundle.setDefusable(bOptions, true);
7119
7120        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7121        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7122        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7123        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7124                |PendingIntent.FLAG_UPDATE_CURRENT);
7125
7126        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7127                type, packageName, activity, resultWho,
7128                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7129        WeakReference<PendingIntentRecord> ref;
7130        ref = mIntentSenderRecords.get(key);
7131        PendingIntentRecord rec = ref != null ? ref.get() : null;
7132        if (rec != null) {
7133            if (!cancelCurrent) {
7134                if (updateCurrent) {
7135                    if (rec.key.requestIntent != null) {
7136                        rec.key.requestIntent.replaceExtras(intents != null ?
7137                                intents[intents.length - 1] : null);
7138                    }
7139                    if (intents != null) {
7140                        intents[intents.length-1] = rec.key.requestIntent;
7141                        rec.key.allIntents = intents;
7142                        rec.key.allResolvedTypes = resolvedTypes;
7143                    } else {
7144                        rec.key.allIntents = null;
7145                        rec.key.allResolvedTypes = null;
7146                    }
7147                }
7148                return rec;
7149            }
7150            rec.canceled = true;
7151            mIntentSenderRecords.remove(key);
7152        }
7153        if (noCreate) {
7154            return rec;
7155        }
7156        rec = new PendingIntentRecord(this, key, callingUid);
7157        mIntentSenderRecords.put(key, rec.ref);
7158        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7159            if (activity.pendingResults == null) {
7160                activity.pendingResults
7161                        = new HashSet<WeakReference<PendingIntentRecord>>();
7162            }
7163            activity.pendingResults.add(rec.ref);
7164        }
7165        return rec;
7166    }
7167
7168    @Override
7169    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7170            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7171        if (target instanceof PendingIntentRecord) {
7172            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7173                    finishedReceiver, requiredPermission, options);
7174        } else {
7175            if (intent == null) {
7176                // Weird case: someone has given us their own custom IIntentSender, and now
7177                // they have someone else trying to send to it but of course this isn't
7178                // really a PendingIntent, so there is no base Intent, and the caller isn't
7179                // supplying an Intent... but we never want to dispatch a null Intent to
7180                // a receiver, so um...  let's make something up.
7181                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7182                intent = new Intent(Intent.ACTION_MAIN);
7183            }
7184            try {
7185                target.send(code, intent, resolvedType, null, requiredPermission, options);
7186            } catch (RemoteException e) {
7187            }
7188            // Platform code can rely on getting a result back when the send is done, but if
7189            // this intent sender is from outside of the system we can't rely on it doing that.
7190            // So instead we don't give it the result receiver, and instead just directly
7191            // report the finish immediately.
7192            if (finishedReceiver != null) {
7193                try {
7194                    finishedReceiver.performReceive(intent, 0,
7195                            null, null, false, false, UserHandle.getCallingUserId());
7196                } catch (RemoteException e) {
7197                }
7198            }
7199            return 0;
7200        }
7201    }
7202
7203    /**
7204     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7205     *
7206     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7207     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7208     */
7209    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7210        if (DEBUG_WHITELISTS) {
7211            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7212                    + targetUid + ", " + duration + ")");
7213        }
7214        synchronized (mPidsSelfLocked) {
7215            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7216            if (pr == null) {
7217                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7218                return;
7219            }
7220            if (!pr.whitelistManager) {
7221                if (DEBUG_WHITELISTS) {
7222                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7223                            + callerPid + " is not allowed");
7224                }
7225                return;
7226            }
7227        }
7228
7229        final long token = Binder.clearCallingIdentity();
7230        try {
7231            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7232                    true, "pe from uid:" + callerUid);
7233        } finally {
7234            Binder.restoreCallingIdentity(token);
7235        }
7236    }
7237
7238    @Override
7239    public void cancelIntentSender(IIntentSender sender) {
7240        if (!(sender instanceof PendingIntentRecord)) {
7241            return;
7242        }
7243        synchronized(this) {
7244            PendingIntentRecord rec = (PendingIntentRecord)sender;
7245            try {
7246                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7247                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7248                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7249                    String msg = "Permission Denial: cancelIntentSender() from pid="
7250                        + Binder.getCallingPid()
7251                        + ", uid=" + Binder.getCallingUid()
7252                        + " is not allowed to cancel packges "
7253                        + rec.key.packageName;
7254                    Slog.w(TAG, msg);
7255                    throw new SecurityException(msg);
7256                }
7257            } catch (RemoteException e) {
7258                throw new SecurityException(e);
7259            }
7260            cancelIntentSenderLocked(rec, true);
7261        }
7262    }
7263
7264    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7265        rec.canceled = true;
7266        mIntentSenderRecords.remove(rec.key);
7267        if (cleanActivity && rec.key.activity != null) {
7268            rec.key.activity.pendingResults.remove(rec.ref);
7269        }
7270    }
7271
7272    @Override
7273    public String getPackageForIntentSender(IIntentSender pendingResult) {
7274        if (!(pendingResult instanceof PendingIntentRecord)) {
7275            return null;
7276        }
7277        try {
7278            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7279            return res.key.packageName;
7280        } catch (ClassCastException e) {
7281        }
7282        return null;
7283    }
7284
7285    @Override
7286    public int getUidForIntentSender(IIntentSender sender) {
7287        if (sender instanceof PendingIntentRecord) {
7288            try {
7289                PendingIntentRecord res = (PendingIntentRecord)sender;
7290                return res.uid;
7291            } catch (ClassCastException e) {
7292            }
7293        }
7294        return -1;
7295    }
7296
7297    @Override
7298    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7299        if (!(pendingResult instanceof PendingIntentRecord)) {
7300            return false;
7301        }
7302        try {
7303            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7304            if (res.key.allIntents == null) {
7305                return false;
7306            }
7307            for (int i=0; i<res.key.allIntents.length; i++) {
7308                Intent intent = res.key.allIntents[i];
7309                if (intent.getPackage() != null && intent.getComponent() != null) {
7310                    return false;
7311                }
7312            }
7313            return true;
7314        } catch (ClassCastException e) {
7315        }
7316        return false;
7317    }
7318
7319    @Override
7320    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7321        if (!(pendingResult instanceof PendingIntentRecord)) {
7322            return false;
7323        }
7324        try {
7325            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7326            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7327                return true;
7328            }
7329            return false;
7330        } catch (ClassCastException e) {
7331        }
7332        return false;
7333    }
7334
7335    @Override
7336    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7337        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7338                "getIntentForIntentSender()");
7339        if (!(pendingResult instanceof PendingIntentRecord)) {
7340            return null;
7341        }
7342        try {
7343            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7345        } catch (ClassCastException e) {
7346        }
7347        return null;
7348    }
7349
7350    @Override
7351    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7352        if (!(pendingResult instanceof PendingIntentRecord)) {
7353            return null;
7354        }
7355        try {
7356            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7357            synchronized (this) {
7358                return getTagForIntentSenderLocked(res, prefix);
7359            }
7360        } catch (ClassCastException e) {
7361        }
7362        return null;
7363    }
7364
7365    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7366        final Intent intent = res.key.requestIntent;
7367        if (intent != null) {
7368            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7369                    || res.lastTagPrefix.equals(prefix))) {
7370                return res.lastTag;
7371            }
7372            res.lastTagPrefix = prefix;
7373            final StringBuilder sb = new StringBuilder(128);
7374            if (prefix != null) {
7375                sb.append(prefix);
7376            }
7377            if (intent.getAction() != null) {
7378                sb.append(intent.getAction());
7379            } else if (intent.getComponent() != null) {
7380                intent.getComponent().appendShortString(sb);
7381            } else {
7382                sb.append("?");
7383            }
7384            return res.lastTag = sb.toString();
7385        }
7386        return null;
7387    }
7388
7389    @Override
7390    public void setProcessLimit(int max) {
7391        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7392                "setProcessLimit()");
7393        synchronized (this) {
7394            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7395            mProcessLimitOverride = max;
7396        }
7397        trimApplications();
7398    }
7399
7400    @Override
7401    public int getProcessLimit() {
7402        synchronized (this) {
7403            return mProcessLimitOverride;
7404        }
7405    }
7406
7407    void foregroundTokenDied(ForegroundToken token) {
7408        synchronized (ActivityManagerService.this) {
7409            synchronized (mPidsSelfLocked) {
7410                ForegroundToken cur
7411                    = mForegroundProcesses.get(token.pid);
7412                if (cur != token) {
7413                    return;
7414                }
7415                mForegroundProcesses.remove(token.pid);
7416                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7417                if (pr == null) {
7418                    return;
7419                }
7420                pr.forcingToForeground = null;
7421                updateProcessForegroundLocked(pr, false, false);
7422            }
7423            updateOomAdjLocked();
7424        }
7425    }
7426
7427    @Override
7428    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7429        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7430                "setProcessForeground()");
7431        synchronized(this) {
7432            boolean changed = false;
7433
7434            synchronized (mPidsSelfLocked) {
7435                ProcessRecord pr = mPidsSelfLocked.get(pid);
7436                if (pr == null && isForeground) {
7437                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7438                    return;
7439                }
7440                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7441                if (oldToken != null) {
7442                    oldToken.token.unlinkToDeath(oldToken, 0);
7443                    mForegroundProcesses.remove(pid);
7444                    if (pr != null) {
7445                        pr.forcingToForeground = null;
7446                    }
7447                    changed = true;
7448                }
7449                if (isForeground && token != null) {
7450                    ForegroundToken newToken = new ForegroundToken() {
7451                        @Override
7452                        public void binderDied() {
7453                            foregroundTokenDied(this);
7454                        }
7455                    };
7456                    newToken.pid = pid;
7457                    newToken.token = token;
7458                    try {
7459                        token.linkToDeath(newToken, 0);
7460                        mForegroundProcesses.put(pid, newToken);
7461                        pr.forcingToForeground = token;
7462                        changed = true;
7463                    } catch (RemoteException e) {
7464                        // If the process died while doing this, we will later
7465                        // do the cleanup with the process death link.
7466                    }
7467                }
7468            }
7469
7470            if (changed) {
7471                updateOomAdjLocked();
7472            }
7473        }
7474    }
7475
7476    @Override
7477    public boolean isAppForeground(int uid) throws RemoteException {
7478        synchronized (this) {
7479            UidRecord uidRec = mActiveUids.get(uid);
7480            if (uidRec == null || uidRec.idle) {
7481                return false;
7482            }
7483            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7484        }
7485    }
7486
7487    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7488    // be guarded by permission checking.
7489    int getUidState(int uid) {
7490        synchronized (this) {
7491            UidRecord uidRec = mActiveUids.get(uid);
7492            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7493        }
7494    }
7495
7496    @Override
7497    public boolean isInMultiWindowMode(IBinder token) {
7498        final long origId = Binder.clearCallingIdentity();
7499        try {
7500            synchronized(this) {
7501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7502                if (r == null) {
7503                    return false;
7504                }
7505                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7506                return !r.task.mFullscreen;
7507            }
7508        } finally {
7509            Binder.restoreCallingIdentity(origId);
7510        }
7511    }
7512
7513    @Override
7514    public boolean isInPictureInPictureMode(IBinder token) {
7515        final long origId = Binder.clearCallingIdentity();
7516        try {
7517            synchronized(this) {
7518                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7519                if (stack == null) {
7520                    return false;
7521                }
7522                return stack.mStackId == PINNED_STACK_ID;
7523            }
7524        } finally {
7525            Binder.restoreCallingIdentity(origId);
7526        }
7527    }
7528
7529    @Override
7530    public void enterPictureInPictureMode(IBinder token) {
7531        final long origId = Binder.clearCallingIdentity();
7532        try {
7533            synchronized(this) {
7534                if (!mSupportsPictureInPicture) {
7535                    throw new IllegalStateException("enterPictureInPictureMode: "
7536                            + "Device doesn't support picture-in-picture mode.");
7537                }
7538
7539                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7540
7541                if (r == null) {
7542                    throw new IllegalStateException("enterPictureInPictureMode: "
7543                            + "Can't find activity for token=" + token);
7544                }
7545
7546                if (!r.supportsPictureInPicture()) {
7547                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7548                            + "Picture-In-Picture not supported for r=" + r);
7549                }
7550
7551                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7552                // current bounds.
7553                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7554                final Rect bounds = (pinnedStack != null)
7555                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7556
7557                mStackSupervisor.moveActivityToPinnedStackLocked(
7558                        r, "enterPictureInPictureMode", bounds);
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(origId);
7562        }
7563    }
7564
7565    // =========================================================
7566    // PROCESS INFO
7567    // =========================================================
7568
7569    static class ProcessInfoService extends IProcessInfoService.Stub {
7570        final ActivityManagerService mActivityManagerService;
7571        ProcessInfoService(ActivityManagerService activityManagerService) {
7572            mActivityManagerService = activityManagerService;
7573        }
7574
7575        @Override
7576        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7577            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7578                    /*in*/ pids, /*out*/ states, null);
7579        }
7580
7581        @Override
7582        public void getProcessStatesAndOomScoresFromPids(
7583                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7584            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7585                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7586        }
7587    }
7588
7589    /**
7590     * For each PID in the given input array, write the current process state
7591     * for that process into the states array, or -1 to indicate that no
7592     * process with the given PID exists. If scores array is provided, write
7593     * the oom score for the process into the scores array, with INVALID_ADJ
7594     * indicating the PID doesn't exist.
7595     */
7596    public void getProcessStatesAndOomScoresForPIDs(
7597            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7598        if (scores != null) {
7599            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7600                    "getProcessStatesAndOomScoresForPIDs()");
7601        }
7602
7603        if (pids == null) {
7604            throw new NullPointerException("pids");
7605        } else if (states == null) {
7606            throw new NullPointerException("states");
7607        } else if (pids.length != states.length) {
7608            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7609        } else if (scores != null && pids.length != scores.length) {
7610            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7611        }
7612
7613        synchronized (mPidsSelfLocked) {
7614            for (int i = 0; i < pids.length; i++) {
7615                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7616                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7617                        pr.curProcState;
7618                if (scores != null) {
7619                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7620                }
7621            }
7622        }
7623    }
7624
7625    // =========================================================
7626    // PERMISSIONS
7627    // =========================================================
7628
7629    static class PermissionController extends IPermissionController.Stub {
7630        ActivityManagerService mActivityManagerService;
7631        PermissionController(ActivityManagerService activityManagerService) {
7632            mActivityManagerService = activityManagerService;
7633        }
7634
7635        @Override
7636        public boolean checkPermission(String permission, int pid, int uid) {
7637            return mActivityManagerService.checkPermission(permission, pid,
7638                    uid) == PackageManager.PERMISSION_GRANTED;
7639        }
7640
7641        @Override
7642        public String[] getPackagesForUid(int uid) {
7643            return mActivityManagerService.mContext.getPackageManager()
7644                    .getPackagesForUid(uid);
7645        }
7646
7647        @Override
7648        public boolean isRuntimePermission(String permission) {
7649            try {
7650                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7651                        .getPermissionInfo(permission, 0);
7652                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7653            } catch (NameNotFoundException nnfe) {
7654                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7655            }
7656            return false;
7657        }
7658    }
7659
7660    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7661        @Override
7662        public int checkComponentPermission(String permission, int pid, int uid,
7663                int owningUid, boolean exported) {
7664            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7665                    owningUid, exported);
7666        }
7667
7668        @Override
7669        public Object getAMSLock() {
7670            return ActivityManagerService.this;
7671        }
7672    }
7673
7674    /**
7675     * This can be called with or without the global lock held.
7676     */
7677    int checkComponentPermission(String permission, int pid, int uid,
7678            int owningUid, boolean exported) {
7679        if (pid == MY_PID) {
7680            return PackageManager.PERMISSION_GRANTED;
7681        }
7682        return ActivityManager.checkComponentPermission(permission, uid,
7683                owningUid, exported);
7684    }
7685
7686    /**
7687     * As the only public entry point for permissions checking, this method
7688     * can enforce the semantic that requesting a check on a null global
7689     * permission is automatically denied.  (Internally a null permission
7690     * string is used when calling {@link #checkComponentPermission} in cases
7691     * when only uid-based security is needed.)
7692     *
7693     * This can be called with or without the global lock held.
7694     */
7695    @Override
7696    public int checkPermission(String permission, int pid, int uid) {
7697        if (permission == null) {
7698            return PackageManager.PERMISSION_DENIED;
7699        }
7700        return checkComponentPermission(permission, pid, uid, -1, true);
7701    }
7702
7703    @Override
7704    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7705        if (permission == null) {
7706            return PackageManager.PERMISSION_DENIED;
7707        }
7708
7709        // We might be performing an operation on behalf of an indirect binder
7710        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7711        // client identity accordingly before proceeding.
7712        Identity tlsIdentity = sCallerIdentity.get();
7713        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7714            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7715                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7716            uid = tlsIdentity.uid;
7717            pid = tlsIdentity.pid;
7718        }
7719
7720        return checkComponentPermission(permission, pid, uid, -1, true);
7721    }
7722
7723    /**
7724     * Binder IPC calls go through the public entry point.
7725     * This can be called with or without the global lock held.
7726     */
7727    int checkCallingPermission(String permission) {
7728        return checkPermission(permission,
7729                Binder.getCallingPid(),
7730                UserHandle.getAppId(Binder.getCallingUid()));
7731    }
7732
7733    /**
7734     * This can be called with or without the global lock held.
7735     */
7736    void enforceCallingPermission(String permission, String func) {
7737        if (checkCallingPermission(permission)
7738                == PackageManager.PERMISSION_GRANTED) {
7739            return;
7740        }
7741
7742        String msg = "Permission Denial: " + func + " from pid="
7743                + Binder.getCallingPid()
7744                + ", uid=" + Binder.getCallingUid()
7745                + " requires " + permission;
7746        Slog.w(TAG, msg);
7747        throw new SecurityException(msg);
7748    }
7749
7750    /**
7751     * Determine if UID is holding permissions required to access {@link Uri} in
7752     * the given {@link ProviderInfo}. Final permission checking is always done
7753     * in {@link ContentProvider}.
7754     */
7755    private final boolean checkHoldingPermissionsLocked(
7756            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7757        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7759        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7760            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7761                    != PERMISSION_GRANTED) {
7762                return false;
7763            }
7764        }
7765        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7766    }
7767
7768    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7769            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7770        if (pi.applicationInfo.uid == uid) {
7771            return true;
7772        } else if (!pi.exported) {
7773            return false;
7774        }
7775
7776        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7777        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7778        try {
7779            // check if target holds top-level <provider> permissions
7780            if (!readMet && pi.readPermission != null && considerUidPermissions
7781                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7782                readMet = true;
7783            }
7784            if (!writeMet && pi.writePermission != null && considerUidPermissions
7785                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7786                writeMet = true;
7787            }
7788
7789            // track if unprotected read/write is allowed; any denied
7790            // <path-permission> below removes this ability
7791            boolean allowDefaultRead = pi.readPermission == null;
7792            boolean allowDefaultWrite = pi.writePermission == null;
7793
7794            // check if target holds any <path-permission> that match uri
7795            final PathPermission[] pps = pi.pathPermissions;
7796            if (pps != null) {
7797                final String path = grantUri.uri.getPath();
7798                int i = pps.length;
7799                while (i > 0 && (!readMet || !writeMet)) {
7800                    i--;
7801                    PathPermission pp = pps[i];
7802                    if (pp.match(path)) {
7803                        if (!readMet) {
7804                            final String pprperm = pp.getReadPermission();
7805                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7807                                    + ": match=" + pp.match(path)
7808                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7809                            if (pprperm != null) {
7810                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7811                                        == PERMISSION_GRANTED) {
7812                                    readMet = true;
7813                                } else {
7814                                    allowDefaultRead = false;
7815                                }
7816                            }
7817                        }
7818                        if (!writeMet) {
7819                            final String ppwperm = pp.getWritePermission();
7820                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7822                                    + ": match=" + pp.match(path)
7823                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7824                            if (ppwperm != null) {
7825                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7826                                        == PERMISSION_GRANTED) {
7827                                    writeMet = true;
7828                                } else {
7829                                    allowDefaultWrite = false;
7830                                }
7831                            }
7832                        }
7833                    }
7834                }
7835            }
7836
7837            // grant unprotected <provider> read/write, if not blocked by
7838            // <path-permission> above
7839            if (allowDefaultRead) readMet = true;
7840            if (allowDefaultWrite) writeMet = true;
7841
7842        } catch (RemoteException e) {
7843            return false;
7844        }
7845
7846        return readMet && writeMet;
7847    }
7848
7849    public int getAppStartMode(int uid, String packageName) {
7850        synchronized (this) {
7851            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7852        }
7853    }
7854
7855    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7856            boolean allowWhenForeground) {
7857        UidRecord uidRec = mActiveUids.get(uid);
7858        if (!mLenientBackgroundCheck) {
7859            if (!allowWhenForeground || uidRec == null
7860                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7861                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7862                        packageName) != AppOpsManager.MODE_ALLOWED) {
7863                    return ActivityManager.APP_START_MODE_DELAYED;
7864                }
7865            }
7866
7867        } else if (uidRec == null || uidRec.idle) {
7868            if (callingPid >= 0) {
7869                ProcessRecord proc;
7870                synchronized (mPidsSelfLocked) {
7871                    proc = mPidsSelfLocked.get(callingPid);
7872                }
7873                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7874                    // Whoever is instigating this is in the foreground, so we will allow it
7875                    // to go through.
7876                    return ActivityManager.APP_START_MODE_NORMAL;
7877                }
7878            }
7879            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7880                    != AppOpsManager.MODE_ALLOWED) {
7881                return ActivityManager.APP_START_MODE_DELAYED;
7882            }
7883        }
7884        return ActivityManager.APP_START_MODE_NORMAL;
7885    }
7886
7887    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7888        ProviderInfo pi = null;
7889        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7890        if (cpr != null) {
7891            pi = cpr.info;
7892        } else {
7893            try {
7894                pi = AppGlobals.getPackageManager().resolveContentProvider(
7895                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7896                        userHandle);
7897            } catch (RemoteException ex) {
7898            }
7899        }
7900        return pi;
7901    }
7902
7903    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7904        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7905        if (targetUris != null) {
7906            return targetUris.get(grantUri);
7907        }
7908        return null;
7909    }
7910
7911    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7912            String targetPkg, int targetUid, GrantUri grantUri) {
7913        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7914        if (targetUris == null) {
7915            targetUris = Maps.newArrayMap();
7916            mGrantedUriPermissions.put(targetUid, targetUris);
7917        }
7918
7919        UriPermission perm = targetUris.get(grantUri);
7920        if (perm == null) {
7921            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7922            targetUris.put(grantUri, perm);
7923        }
7924
7925        return perm;
7926    }
7927
7928    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7929            final int modeFlags) {
7930        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7931        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7932                : UriPermission.STRENGTH_OWNED;
7933
7934        // Root gets to do everything.
7935        if (uid == 0) {
7936            return true;
7937        }
7938
7939        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7940        if (perms == null) return false;
7941
7942        // First look for exact match
7943        final UriPermission exactPerm = perms.get(grantUri);
7944        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7945            return true;
7946        }
7947
7948        // No exact match, look for prefixes
7949        final int N = perms.size();
7950        for (int i = 0; i < N; i++) {
7951            final UriPermission perm = perms.valueAt(i);
7952            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7953                    && perm.getStrength(modeFlags) >= minStrength) {
7954                return true;
7955            }
7956        }
7957
7958        return false;
7959    }
7960
7961    /**
7962     * @param uri This uri must NOT contain an embedded userId.
7963     * @param userId The userId in which the uri is to be resolved.
7964     */
7965    @Override
7966    public int checkUriPermission(Uri uri, int pid, int uid,
7967            final int modeFlags, int userId, IBinder callerToken) {
7968        enforceNotIsolatedCaller("checkUriPermission");
7969
7970        // Another redirected-binder-call permissions check as in
7971        // {@link checkPermissionWithToken}.
7972        Identity tlsIdentity = sCallerIdentity.get();
7973        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7974            uid = tlsIdentity.uid;
7975            pid = tlsIdentity.pid;
7976        }
7977
7978        // Our own process gets to do everything.
7979        if (pid == MY_PID) {
7980            return PackageManager.PERMISSION_GRANTED;
7981        }
7982        synchronized (this) {
7983            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7984                    ? PackageManager.PERMISSION_GRANTED
7985                    : PackageManager.PERMISSION_DENIED;
7986        }
7987    }
7988
7989    /**
7990     * Check if the targetPkg can be granted permission to access uri by
7991     * the callingUid using the given modeFlags.  Throws a security exception
7992     * if callingUid is not allowed to do this.  Returns the uid of the target
7993     * if the URI permission grant should be performed; returns -1 if it is not
7994     * needed (for example targetPkg already has permission to access the URI).
7995     * If you already know the uid of the target, you can supply it in
7996     * lastTargetUid else set that to -1.
7997     */
7998    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7999            final int modeFlags, int lastTargetUid) {
8000        if (!Intent.isAccessUriMode(modeFlags)) {
8001            return -1;
8002        }
8003
8004        if (targetPkg != null) {
8005            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8006                    "Checking grant " + targetPkg + " permission to " + grantUri);
8007        }
8008
8009        final IPackageManager pm = AppGlobals.getPackageManager();
8010
8011        // If this is not a content: uri, we can't do anything with it.
8012        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8013            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                    "Can't grant URI permission for non-content URI: " + grantUri);
8015            return -1;
8016        }
8017
8018        final String authority = grantUri.uri.getAuthority();
8019        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8020                MATCH_DEBUG_TRIAGED_MISSING);
8021        if (pi == null) {
8022            Slog.w(TAG, "No content provider found for permission check: " +
8023                    grantUri.uri.toSafeString());
8024            return -1;
8025        }
8026
8027        int targetUid = lastTargetUid;
8028        if (targetUid < 0 && targetPkg != null) {
8029            try {
8030                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8031                        UserHandle.getUserId(callingUid));
8032                if (targetUid < 0) {
8033                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8034                            "Can't grant URI permission no uid for: " + targetPkg);
8035                    return -1;
8036                }
8037            } catch (RemoteException ex) {
8038                return -1;
8039            }
8040        }
8041
8042        if (targetUid >= 0) {
8043            // First...  does the target actually need this permission?
8044            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8045                // No need to grant the target this permission.
8046                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8047                        "Target " + targetPkg + " already has full permission to " + grantUri);
8048                return -1;
8049            }
8050        } else {
8051            // First...  there is no target package, so can anyone access it?
8052            boolean allowed = pi.exported;
8053            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8054                if (pi.readPermission != null) {
8055                    allowed = false;
8056                }
8057            }
8058            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8059                if (pi.writePermission != null) {
8060                    allowed = false;
8061                }
8062            }
8063            if (allowed) {
8064                return -1;
8065            }
8066        }
8067
8068        /* There is a special cross user grant if:
8069         * - The target is on another user.
8070         * - Apps on the current user can access the uri without any uid permissions.
8071         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8072         * grant uri permissions.
8073         */
8074        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8075                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8076                modeFlags, false /*without considering the uid permissions*/);
8077
8078        // Second...  is the provider allowing granting of URI permissions?
8079        if (!specialCrossUserGrant) {
8080            if (!pi.grantUriPermissions) {
8081                throw new SecurityException("Provider " + pi.packageName
8082                        + "/" + pi.name
8083                        + " does not allow granting of Uri permissions (uri "
8084                        + grantUri + ")");
8085            }
8086            if (pi.uriPermissionPatterns != null) {
8087                final int N = pi.uriPermissionPatterns.length;
8088                boolean allowed = false;
8089                for (int i=0; i<N; i++) {
8090                    if (pi.uriPermissionPatterns[i] != null
8091                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8092                        allowed = true;
8093                        break;
8094                    }
8095                }
8096                if (!allowed) {
8097                    throw new SecurityException("Provider " + pi.packageName
8098                            + "/" + pi.name
8099                            + " does not allow granting of permission to path of Uri "
8100                            + grantUri);
8101                }
8102            }
8103        }
8104
8105        // Third...  does the caller itself have permission to access
8106        // this uri?
8107        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8108            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8109                // Require they hold a strong enough Uri permission
8110                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8111                    throw new SecurityException("Uid " + callingUid
8112                            + " does not have permission to uri " + grantUri);
8113                }
8114            }
8115        }
8116        return targetUid;
8117    }
8118
8119    /**
8120     * @param uri This uri must NOT contain an embedded userId.
8121     * @param userId The userId in which the uri is to be resolved.
8122     */
8123    @Override
8124    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8125            final int modeFlags, int userId) {
8126        enforceNotIsolatedCaller("checkGrantUriPermission");
8127        synchronized(this) {
8128            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8129                    new GrantUri(userId, uri, false), modeFlags, -1);
8130        }
8131    }
8132
8133    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8134            final int modeFlags, UriPermissionOwner owner) {
8135        if (!Intent.isAccessUriMode(modeFlags)) {
8136            return;
8137        }
8138
8139        // So here we are: the caller has the assumed permission
8140        // to the uri, and the target doesn't.  Let's now give this to
8141        // the target.
8142
8143        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8144                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8145
8146        final String authority = grantUri.uri.getAuthority();
8147        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8148                MATCH_DEBUG_TRIAGED_MISSING);
8149        if (pi == null) {
8150            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8151            return;
8152        }
8153
8154        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8155            grantUri.prefix = true;
8156        }
8157        final UriPermission perm = findOrCreateUriPermissionLocked(
8158                pi.packageName, targetPkg, targetUid, grantUri);
8159        perm.grantModes(modeFlags, owner);
8160    }
8161
8162    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8163            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8164        if (targetPkg == null) {
8165            throw new NullPointerException("targetPkg");
8166        }
8167        int targetUid;
8168        final IPackageManager pm = AppGlobals.getPackageManager();
8169        try {
8170            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8171        } catch (RemoteException ex) {
8172            return;
8173        }
8174
8175        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8176                targetUid);
8177        if (targetUid < 0) {
8178            return;
8179        }
8180
8181        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8182                owner);
8183    }
8184
8185    static class NeededUriGrants extends ArrayList<GrantUri> {
8186        final String targetPkg;
8187        final int targetUid;
8188        final int flags;
8189
8190        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8191            this.targetPkg = targetPkg;
8192            this.targetUid = targetUid;
8193            this.flags = flags;
8194        }
8195    }
8196
8197    /**
8198     * Like checkGrantUriPermissionLocked, but takes an Intent.
8199     */
8200    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8201            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8202        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8203                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8204                + " clip=" + (intent != null ? intent.getClipData() : null)
8205                + " from " + intent + "; flags=0x"
8206                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8207
8208        if (targetPkg == null) {
8209            throw new NullPointerException("targetPkg");
8210        }
8211
8212        if (intent == null) {
8213            return null;
8214        }
8215        Uri data = intent.getData();
8216        ClipData clip = intent.getClipData();
8217        if (data == null && clip == null) {
8218            return null;
8219        }
8220        // Default userId for uris in the intent (if they don't specify it themselves)
8221        int contentUserHint = intent.getContentUserHint();
8222        if (contentUserHint == UserHandle.USER_CURRENT) {
8223            contentUserHint = UserHandle.getUserId(callingUid);
8224        }
8225        final IPackageManager pm = AppGlobals.getPackageManager();
8226        int targetUid;
8227        if (needed != null) {
8228            targetUid = needed.targetUid;
8229        } else {
8230            try {
8231                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8232                        targetUserId);
8233            } catch (RemoteException ex) {
8234                return null;
8235            }
8236            if (targetUid < 0) {
8237                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8238                        "Can't grant URI permission no uid for: " + targetPkg
8239                        + " on user " + targetUserId);
8240                return null;
8241            }
8242        }
8243        if (data != null) {
8244            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8245            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8246                    targetUid);
8247            if (targetUid > 0) {
8248                if (needed == null) {
8249                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8250                }
8251                needed.add(grantUri);
8252            }
8253        }
8254        if (clip != null) {
8255            for (int i=0; i<clip.getItemCount(); i++) {
8256                Uri uri = clip.getItemAt(i).getUri();
8257                if (uri != null) {
8258                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8259                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8260                            targetUid);
8261                    if (targetUid > 0) {
8262                        if (needed == null) {
8263                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8264                        }
8265                        needed.add(grantUri);
8266                    }
8267                } else {
8268                    Intent clipIntent = clip.getItemAt(i).getIntent();
8269                    if (clipIntent != null) {
8270                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8271                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8272                        if (newNeeded != null) {
8273                            needed = newNeeded;
8274                        }
8275                    }
8276                }
8277            }
8278        }
8279
8280        return needed;
8281    }
8282
8283    /**
8284     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8285     */
8286    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8287            UriPermissionOwner owner) {
8288        if (needed != null) {
8289            for (int i=0; i<needed.size(); i++) {
8290                GrantUri grantUri = needed.get(i);
8291                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8292                        grantUri, needed.flags, owner);
8293            }
8294        }
8295    }
8296
8297    void grantUriPermissionFromIntentLocked(int callingUid,
8298            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8299        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8300                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8301        if (needed == null) {
8302            return;
8303        }
8304
8305        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8306    }
8307
8308    /**
8309     * @param uri This uri must NOT contain an embedded userId.
8310     * @param userId The userId in which the uri is to be resolved.
8311     */
8312    @Override
8313    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8314            final int modeFlags, int userId) {
8315        enforceNotIsolatedCaller("grantUriPermission");
8316        GrantUri grantUri = new GrantUri(userId, uri, false);
8317        synchronized(this) {
8318            final ProcessRecord r = getRecordForAppLocked(caller);
8319            if (r == null) {
8320                throw new SecurityException("Unable to find app for caller "
8321                        + caller
8322                        + " when granting permission to uri " + grantUri);
8323            }
8324            if (targetPkg == null) {
8325                throw new IllegalArgumentException("null target");
8326            }
8327            if (grantUri == null) {
8328                throw new IllegalArgumentException("null uri");
8329            }
8330
8331            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8332                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8333                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8334                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8335
8336            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8337                    UserHandle.getUserId(r.uid));
8338        }
8339    }
8340
8341    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8342        if (perm.modeFlags == 0) {
8343            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8344                    perm.targetUid);
8345            if (perms != null) {
8346                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8347                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8348
8349                perms.remove(perm.uri);
8350                if (perms.isEmpty()) {
8351                    mGrantedUriPermissions.remove(perm.targetUid);
8352                }
8353            }
8354        }
8355    }
8356
8357    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8358        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8359                "Revoking all granted permissions to " + grantUri);
8360
8361        final IPackageManager pm = AppGlobals.getPackageManager();
8362        final String authority = grantUri.uri.getAuthority();
8363        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8364                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8365        if (pi == null) {
8366            Slog.w(TAG, "No content provider found for permission revoke: "
8367                    + grantUri.toSafeString());
8368            return;
8369        }
8370
8371        // Does the caller have this permission on the URI?
8372        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8373            // If they don't have direct access to the URI, then revoke any
8374            // ownerless URI permissions that have been granted to them.
8375            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8376            if (perms != null) {
8377                boolean persistChanged = false;
8378                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8379                    final UriPermission perm = it.next();
8380                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8381                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8382                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8383                                "Revoking non-owned " + perm.targetUid
8384                                + " permission to " + perm.uri);
8385                        persistChanged |= perm.revokeModes(
8386                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8387                        if (perm.modeFlags == 0) {
8388                            it.remove();
8389                        }
8390                    }
8391                }
8392                if (perms.isEmpty()) {
8393                    mGrantedUriPermissions.remove(callingUid);
8394                }
8395                if (persistChanged) {
8396                    schedulePersistUriGrants();
8397                }
8398            }
8399            return;
8400        }
8401
8402        boolean persistChanged = false;
8403
8404        // Go through all of the permissions and remove any that match.
8405        int N = mGrantedUriPermissions.size();
8406        for (int i = 0; i < N; i++) {
8407            final int targetUid = mGrantedUriPermissions.keyAt(i);
8408            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8409
8410            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8411                final UriPermission perm = it.next();
8412                if (perm.uri.sourceUserId == grantUri.sourceUserId
8413                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8414                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8415                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8416                    persistChanged |= perm.revokeModes(
8417                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8418                    if (perm.modeFlags == 0) {
8419                        it.remove();
8420                    }
8421                }
8422            }
8423
8424            if (perms.isEmpty()) {
8425                mGrantedUriPermissions.remove(targetUid);
8426                N--;
8427                i--;
8428            }
8429        }
8430
8431        if (persistChanged) {
8432            schedulePersistUriGrants();
8433        }
8434    }
8435
8436    /**
8437     * @param uri This uri must NOT contain an embedded userId.
8438     * @param userId The userId in which the uri is to be resolved.
8439     */
8440    @Override
8441    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8442            int userId) {
8443        enforceNotIsolatedCaller("revokeUriPermission");
8444        synchronized(this) {
8445            final ProcessRecord r = getRecordForAppLocked(caller);
8446            if (r == null) {
8447                throw new SecurityException("Unable to find app for caller "
8448                        + caller
8449                        + " when revoking permission to uri " + uri);
8450            }
8451            if (uri == null) {
8452                Slog.w(TAG, "revokeUriPermission: null uri");
8453                return;
8454            }
8455
8456            if (!Intent.isAccessUriMode(modeFlags)) {
8457                return;
8458            }
8459
8460            final String authority = uri.getAuthority();
8461            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8462                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8463            if (pi == null) {
8464                Slog.w(TAG, "No content provider found for permission revoke: "
8465                        + uri.toSafeString());
8466                return;
8467            }
8468
8469            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8470        }
8471    }
8472
8473    /**
8474     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8475     * given package.
8476     *
8477     * @param packageName Package name to match, or {@code null} to apply to all
8478     *            packages.
8479     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8480     *            to all users.
8481     * @param persistable If persistable grants should be removed.
8482     */
8483    private void removeUriPermissionsForPackageLocked(
8484            String packageName, int userHandle, boolean persistable) {
8485        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8486            throw new IllegalArgumentException("Must narrow by either package or user");
8487        }
8488
8489        boolean persistChanged = false;
8490
8491        int N = mGrantedUriPermissions.size();
8492        for (int i = 0; i < N; i++) {
8493            final int targetUid = mGrantedUriPermissions.keyAt(i);
8494            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8495
8496            // Only inspect grants matching user
8497            if (userHandle == UserHandle.USER_ALL
8498                    || userHandle == UserHandle.getUserId(targetUid)) {
8499                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8500                    final UriPermission perm = it.next();
8501
8502                    // Only inspect grants matching package
8503                    if (packageName == null || perm.sourcePkg.equals(packageName)
8504                            || perm.targetPkg.equals(packageName)) {
8505                        persistChanged |= perm.revokeModes(persistable
8506                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8507
8508                        // Only remove when no modes remain; any persisted grants
8509                        // will keep this alive.
8510                        if (perm.modeFlags == 0) {
8511                            it.remove();
8512                        }
8513                    }
8514                }
8515
8516                if (perms.isEmpty()) {
8517                    mGrantedUriPermissions.remove(targetUid);
8518                    N--;
8519                    i--;
8520                }
8521            }
8522        }
8523
8524        if (persistChanged) {
8525            schedulePersistUriGrants();
8526        }
8527    }
8528
8529    @Override
8530    public IBinder newUriPermissionOwner(String name) {
8531        enforceNotIsolatedCaller("newUriPermissionOwner");
8532        synchronized(this) {
8533            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8534            return owner.getExternalTokenLocked();
8535        }
8536    }
8537
8538    @Override
8539    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8540        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8541        synchronized(this) {
8542            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8543            if (r == null) {
8544                throw new IllegalArgumentException("Activity does not exist; token="
8545                        + activityToken);
8546            }
8547            return r.getUriPermissionsLocked().getExternalTokenLocked();
8548        }
8549    }
8550    /**
8551     * @param uri This uri must NOT contain an embedded userId.
8552     * @param sourceUserId The userId in which the uri is to be resolved.
8553     * @param targetUserId The userId of the app that receives the grant.
8554     */
8555    @Override
8556    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8557            final int modeFlags, int sourceUserId, int targetUserId) {
8558        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8559                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8560                "grantUriPermissionFromOwner", null);
8561        synchronized(this) {
8562            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8563            if (owner == null) {
8564                throw new IllegalArgumentException("Unknown owner: " + token);
8565            }
8566            if (fromUid != Binder.getCallingUid()) {
8567                if (Binder.getCallingUid() != Process.myUid()) {
8568                    // Only system code can grant URI permissions on behalf
8569                    // of other users.
8570                    throw new SecurityException("nice try");
8571                }
8572            }
8573            if (targetPkg == null) {
8574                throw new IllegalArgumentException("null target");
8575            }
8576            if (uri == null) {
8577                throw new IllegalArgumentException("null uri");
8578            }
8579
8580            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8581                    modeFlags, owner, targetUserId);
8582        }
8583    }
8584
8585    /**
8586     * @param uri This uri must NOT contain an embedded userId.
8587     * @param userId The userId in which the uri is to be resolved.
8588     */
8589    @Override
8590    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8591        synchronized(this) {
8592            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8593            if (owner == null) {
8594                throw new IllegalArgumentException("Unknown owner: " + token);
8595            }
8596
8597            if (uri == null) {
8598                owner.removeUriPermissionsLocked(mode);
8599            } else {
8600                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8601            }
8602        }
8603    }
8604
8605    private void schedulePersistUriGrants() {
8606        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8607            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8608                    10 * DateUtils.SECOND_IN_MILLIS);
8609        }
8610    }
8611
8612    private void writeGrantedUriPermissions() {
8613        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8614
8615        // Snapshot permissions so we can persist without lock
8616        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8617        synchronized (this) {
8618            final int size = mGrantedUriPermissions.size();
8619            for (int i = 0; i < size; i++) {
8620                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8621                for (UriPermission perm : perms.values()) {
8622                    if (perm.persistedModeFlags != 0) {
8623                        persist.add(perm.snapshot());
8624                    }
8625                }
8626            }
8627        }
8628
8629        FileOutputStream fos = null;
8630        try {
8631            fos = mGrantFile.startWrite();
8632
8633            XmlSerializer out = new FastXmlSerializer();
8634            out.setOutput(fos, StandardCharsets.UTF_8.name());
8635            out.startDocument(null, true);
8636            out.startTag(null, TAG_URI_GRANTS);
8637            for (UriPermission.Snapshot perm : persist) {
8638                out.startTag(null, TAG_URI_GRANT);
8639                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8640                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8641                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8642                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8643                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8644                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8645                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8646                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8647                out.endTag(null, TAG_URI_GRANT);
8648            }
8649            out.endTag(null, TAG_URI_GRANTS);
8650            out.endDocument();
8651
8652            mGrantFile.finishWrite(fos);
8653        } catch (IOException e) {
8654            if (fos != null) {
8655                mGrantFile.failWrite(fos);
8656            }
8657        }
8658    }
8659
8660    private void readGrantedUriPermissionsLocked() {
8661        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8662
8663        final long now = System.currentTimeMillis();
8664
8665        FileInputStream fis = null;
8666        try {
8667            fis = mGrantFile.openRead();
8668            final XmlPullParser in = Xml.newPullParser();
8669            in.setInput(fis, StandardCharsets.UTF_8.name());
8670
8671            int type;
8672            while ((type = in.next()) != END_DOCUMENT) {
8673                final String tag = in.getName();
8674                if (type == START_TAG) {
8675                    if (TAG_URI_GRANT.equals(tag)) {
8676                        final int sourceUserId;
8677                        final int targetUserId;
8678                        final int userHandle = readIntAttribute(in,
8679                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8680                        if (userHandle != UserHandle.USER_NULL) {
8681                            // For backwards compatibility.
8682                            sourceUserId = userHandle;
8683                            targetUserId = userHandle;
8684                        } else {
8685                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8686                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8687                        }
8688                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8689                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8690                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8691                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8692                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8693                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8694
8695                        // Sanity check that provider still belongs to source package
8696                        // Both direct boot aware and unaware packages are fine as we
8697                        // will do filtering at query time to avoid multiple parsing.
8698                        final ProviderInfo pi = getProviderInfoLocked(
8699                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8700                                        | MATCH_DIRECT_BOOT_UNAWARE);
8701                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8702                            int targetUid = -1;
8703                            try {
8704                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8705                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8706                            } catch (RemoteException e) {
8707                            }
8708                            if (targetUid != -1) {
8709                                final UriPermission perm = findOrCreateUriPermissionLocked(
8710                                        sourcePkg, targetPkg, targetUid,
8711                                        new GrantUri(sourceUserId, uri, prefix));
8712                                perm.initPersistedModes(modeFlags, createdTime);
8713                            }
8714                        } else {
8715                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8716                                    + " but instead found " + pi);
8717                        }
8718                    }
8719                }
8720            }
8721        } catch (FileNotFoundException e) {
8722            // Missing grants is okay
8723        } catch (IOException e) {
8724            Slog.wtf(TAG, "Failed reading Uri grants", e);
8725        } catch (XmlPullParserException e) {
8726            Slog.wtf(TAG, "Failed reading Uri grants", e);
8727        } finally {
8728            IoUtils.closeQuietly(fis);
8729        }
8730    }
8731
8732    /**
8733     * @param uri This uri must NOT contain an embedded userId.
8734     * @param userId The userId in which the uri is to be resolved.
8735     */
8736    @Override
8737    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8738        enforceNotIsolatedCaller("takePersistableUriPermission");
8739
8740        Preconditions.checkFlagsArgument(modeFlags,
8741                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8742
8743        synchronized (this) {
8744            final int callingUid = Binder.getCallingUid();
8745            boolean persistChanged = false;
8746            GrantUri grantUri = new GrantUri(userId, uri, false);
8747
8748            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8749                    new GrantUri(userId, uri, false));
8750            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8751                    new GrantUri(userId, uri, true));
8752
8753            final boolean exactValid = (exactPerm != null)
8754                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8755            final boolean prefixValid = (prefixPerm != null)
8756                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8757
8758            if (!(exactValid || prefixValid)) {
8759                throw new SecurityException("No persistable permission grants found for UID "
8760                        + callingUid + " and Uri " + grantUri.toSafeString());
8761            }
8762
8763            if (exactValid) {
8764                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8765            }
8766            if (prefixValid) {
8767                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8768            }
8769
8770            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8771
8772            if (persistChanged) {
8773                schedulePersistUriGrants();
8774            }
8775        }
8776    }
8777
8778    /**
8779     * @param uri This uri must NOT contain an embedded userId.
8780     * @param userId The userId in which the uri is to be resolved.
8781     */
8782    @Override
8783    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8784        enforceNotIsolatedCaller("releasePersistableUriPermission");
8785
8786        Preconditions.checkFlagsArgument(modeFlags,
8787                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8788
8789        synchronized (this) {
8790            final int callingUid = Binder.getCallingUid();
8791            boolean persistChanged = false;
8792
8793            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8794                    new GrantUri(userId, uri, false));
8795            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8796                    new GrantUri(userId, uri, true));
8797            if (exactPerm == null && prefixPerm == null) {
8798                throw new SecurityException("No permission grants found for UID " + callingUid
8799                        + " and Uri " + uri.toSafeString());
8800            }
8801
8802            if (exactPerm != null) {
8803                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8804                removeUriPermissionIfNeededLocked(exactPerm);
8805            }
8806            if (prefixPerm != null) {
8807                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8808                removeUriPermissionIfNeededLocked(prefixPerm);
8809            }
8810
8811            if (persistChanged) {
8812                schedulePersistUriGrants();
8813            }
8814        }
8815    }
8816
8817    /**
8818     * Prune any older {@link UriPermission} for the given UID until outstanding
8819     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8820     *
8821     * @return if any mutations occured that require persisting.
8822     */
8823    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8824        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8825        if (perms == null) return false;
8826        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8827
8828        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8829        for (UriPermission perm : perms.values()) {
8830            if (perm.persistedModeFlags != 0) {
8831                persisted.add(perm);
8832            }
8833        }
8834
8835        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8836        if (trimCount <= 0) return false;
8837
8838        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8839        for (int i = 0; i < trimCount; i++) {
8840            final UriPermission perm = persisted.get(i);
8841
8842            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8843                    "Trimming grant created at " + perm.persistedCreateTime);
8844
8845            perm.releasePersistableModes(~0);
8846            removeUriPermissionIfNeededLocked(perm);
8847        }
8848
8849        return true;
8850    }
8851
8852    @Override
8853    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8854            String packageName, boolean incoming) {
8855        enforceNotIsolatedCaller("getPersistedUriPermissions");
8856        Preconditions.checkNotNull(packageName, "packageName");
8857
8858        final int callingUid = Binder.getCallingUid();
8859        final int callingUserId = UserHandle.getUserId(callingUid);
8860        final IPackageManager pm = AppGlobals.getPackageManager();
8861        try {
8862            final int packageUid = pm.getPackageUid(packageName,
8863                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8864            if (packageUid != callingUid) {
8865                throw new SecurityException(
8866                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8867            }
8868        } catch (RemoteException e) {
8869            throw new SecurityException("Failed to verify package name ownership");
8870        }
8871
8872        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8873        synchronized (this) {
8874            if (incoming) {
8875                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8876                        callingUid);
8877                if (perms == null) {
8878                    Slog.w(TAG, "No permission grants found for " + packageName);
8879                } else {
8880                    for (UriPermission perm : perms.values()) {
8881                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8882                            result.add(perm.buildPersistedPublicApiObject());
8883                        }
8884                    }
8885                }
8886            } else {
8887                final int size = mGrantedUriPermissions.size();
8888                for (int i = 0; i < size; i++) {
8889                    final ArrayMap<GrantUri, UriPermission> perms =
8890                            mGrantedUriPermissions.valueAt(i);
8891                    for (UriPermission perm : perms.values()) {
8892                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8893                            result.add(perm.buildPersistedPublicApiObject());
8894                        }
8895                    }
8896                }
8897            }
8898        }
8899        return new ParceledListSlice<android.content.UriPermission>(result);
8900    }
8901
8902    @Override
8903    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8904            String packageName, int userId) {
8905        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8906                "getGrantedUriPermissions");
8907
8908        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8909        synchronized (this) {
8910            final int size = mGrantedUriPermissions.size();
8911            for (int i = 0; i < size; i++) {
8912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8913                for (UriPermission perm : perms.values()) {
8914                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8915                            && perm.persistedModeFlags != 0) {
8916                        result.add(perm.buildPersistedPublicApiObject());
8917                    }
8918                }
8919            }
8920        }
8921        return new ParceledListSlice<android.content.UriPermission>(result);
8922    }
8923
8924    @Override
8925    public void clearGrantedUriPermissions(String packageName, int userId) {
8926        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8927                "clearGrantedUriPermissions");
8928        removeUriPermissionsForPackageLocked(packageName, userId, true);
8929    }
8930
8931    @Override
8932    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8933        synchronized (this) {
8934            ProcessRecord app =
8935                who != null ? getRecordForAppLocked(who) : null;
8936            if (app == null) return;
8937
8938            Message msg = Message.obtain();
8939            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8940            msg.obj = app;
8941            msg.arg1 = waiting ? 1 : 0;
8942            mUiHandler.sendMessage(msg);
8943        }
8944    }
8945
8946    @Override
8947    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8948        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8949        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8950        outInfo.availMem = Process.getFreeMemory();
8951        outInfo.totalMem = Process.getTotalMemory();
8952        outInfo.threshold = homeAppMem;
8953        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8954        outInfo.hiddenAppThreshold = cachedAppMem;
8955        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8956                ProcessList.SERVICE_ADJ);
8957        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8958                ProcessList.VISIBLE_APP_ADJ);
8959        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8960                ProcessList.FOREGROUND_APP_ADJ);
8961    }
8962
8963    // =========================================================
8964    // TASK MANAGEMENT
8965    // =========================================================
8966
8967    @Override
8968    public List<IAppTask> getAppTasks(String callingPackage) {
8969        int callingUid = Binder.getCallingUid();
8970        long ident = Binder.clearCallingIdentity();
8971
8972        synchronized(this) {
8973            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8974            try {
8975                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8976
8977                final int N = mRecentTasks.size();
8978                for (int i = 0; i < N; i++) {
8979                    TaskRecord tr = mRecentTasks.get(i);
8980                    // Skip tasks that do not match the caller.  We don't need to verify
8981                    // callingPackage, because we are also limiting to callingUid and know
8982                    // that will limit to the correct security sandbox.
8983                    if (tr.effectiveUid != callingUid) {
8984                        continue;
8985                    }
8986                    Intent intent = tr.getBaseIntent();
8987                    if (intent == null ||
8988                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8989                        continue;
8990                    }
8991                    ActivityManager.RecentTaskInfo taskInfo =
8992                            createRecentTaskInfoFromTaskRecord(tr);
8993                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8994                    list.add(taskImpl);
8995                }
8996            } finally {
8997                Binder.restoreCallingIdentity(ident);
8998            }
8999            return list;
9000        }
9001    }
9002
9003    @Override
9004    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9005        final int callingUid = Binder.getCallingUid();
9006        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9007
9008        synchronized(this) {
9009            if (DEBUG_ALL) Slog.v(
9010                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9011
9012            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9013                    callingUid);
9014
9015            // TODO: Improve with MRU list from all ActivityStacks.
9016            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9017        }
9018
9019        return list;
9020    }
9021
9022    /**
9023     * Creates a new RecentTaskInfo from a TaskRecord.
9024     */
9025    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9026        // Update the task description to reflect any changes in the task stack
9027        tr.updateTaskDescription();
9028
9029        // Compose the recent task info
9030        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9031        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9032        rti.persistentId = tr.taskId;
9033        rti.baseIntent = new Intent(tr.getBaseIntent());
9034        rti.origActivity = tr.origActivity;
9035        rti.realActivity = tr.realActivity;
9036        rti.description = tr.lastDescription;
9037        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9038        rti.userId = tr.userId;
9039        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9040        rti.firstActiveTime = tr.firstActiveTime;
9041        rti.lastActiveTime = tr.lastActiveTime;
9042        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9043        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9044        rti.numActivities = 0;
9045        if (tr.mBounds != null) {
9046            rti.bounds = new Rect(tr.mBounds);
9047        }
9048        rti.isDockable = tr.canGoInDockedStack();
9049        rti.resizeMode = tr.mResizeMode;
9050
9051        ActivityRecord base = null;
9052        ActivityRecord top = null;
9053        ActivityRecord tmp;
9054
9055        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9056            tmp = tr.mActivities.get(i);
9057            if (tmp.finishing) {
9058                continue;
9059            }
9060            base = tmp;
9061            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9062                top = base;
9063            }
9064            rti.numActivities++;
9065        }
9066
9067        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9068        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9069
9070        return rti;
9071    }
9072
9073    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9074        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9075                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9076        if (!allowed) {
9077            if (checkPermission(android.Manifest.permission.GET_TASKS,
9078                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9079                // Temporary compatibility: some existing apps on the system image may
9080                // still be requesting the old permission and not switched to the new
9081                // one; if so, we'll still allow them full access.  This means we need
9082                // to see if they are holding the old permission and are a system app.
9083                try {
9084                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9085                        allowed = true;
9086                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9087                                + " is using old GET_TASKS but privileged; allowing");
9088                    }
9089                } catch (RemoteException e) {
9090                }
9091            }
9092        }
9093        if (!allowed) {
9094            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9095                    + " does not hold REAL_GET_TASKS; limiting output");
9096        }
9097        return allowed;
9098    }
9099
9100    @Override
9101    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9102            int userId) {
9103        final int callingUid = Binder.getCallingUid();
9104        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9105                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9106
9107        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9108        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9109        synchronized (this) {
9110            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9111                    callingUid);
9112            final boolean detailed = checkCallingPermission(
9113                    android.Manifest.permission.GET_DETAILED_TASKS)
9114                    == PackageManager.PERMISSION_GRANTED;
9115
9116            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9117                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9118                return ParceledListSlice.emptyList();
9119            }
9120            mRecentTasks.loadUserRecentsLocked(userId);
9121
9122            final int recentsCount = mRecentTasks.size();
9123            ArrayList<ActivityManager.RecentTaskInfo> res =
9124                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9125
9126            final Set<Integer> includedUsers;
9127            if (includeProfiles) {
9128                includedUsers = mUserController.getProfileIds(userId);
9129            } else {
9130                includedUsers = new HashSet<>();
9131            }
9132            includedUsers.add(Integer.valueOf(userId));
9133
9134            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9135                TaskRecord tr = mRecentTasks.get(i);
9136                // Only add calling user or related users recent tasks
9137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9138                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9139                    continue;
9140                }
9141
9142                if (tr.realActivitySuspended) {
9143                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9144                    continue;
9145                }
9146
9147                // Return the entry if desired by the caller.  We always return
9148                // the first entry, because callers always expect this to be the
9149                // foreground app.  We may filter others if the caller has
9150                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9151                // we should exclude the entry.
9152
9153                if (i == 0
9154                        || withExcluded
9155                        || (tr.intent == null)
9156                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9157                                == 0)) {
9158                    if (!allowed) {
9159                        // If the caller doesn't have the GET_TASKS permission, then only
9160                        // allow them to see a small subset of tasks -- their own and home.
9161                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9163                            continue;
9164                        }
9165                    }
9166                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9167                        if (tr.stack != null && tr.stack.isHomeStack()) {
9168                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                    "Skipping, home stack task: " + tr);
9170                            continue;
9171                        }
9172                    }
9173                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9174                        final ActivityStack stack = tr.stack;
9175                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9176                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9177                                    "Skipping, top task in docked stack: " + tr);
9178                            continue;
9179                        }
9180                    }
9181                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9182                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9183                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                    "Skipping, pinned stack task: " + tr);
9185                            continue;
9186                        }
9187                    }
9188                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9189                        // Don't include auto remove tasks that are finished or finishing.
9190                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9191                                "Skipping, auto-remove without activity: " + tr);
9192                        continue;
9193                    }
9194                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9195                            && !tr.isAvailable) {
9196                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9197                                "Skipping, unavail real act: " + tr);
9198                        continue;
9199                    }
9200
9201                    if (!tr.mUserSetupComplete) {
9202                        // Don't include task launched while user is not done setting-up.
9203                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9204                                "Skipping, user setup not complete: " + tr);
9205                        continue;
9206                    }
9207
9208                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9209                    if (!detailed) {
9210                        rti.baseIntent.replaceExtras((Bundle)null);
9211                    }
9212
9213                    res.add(rti);
9214                    maxNum--;
9215                }
9216            }
9217            return new ParceledListSlice<>(res);
9218        }
9219    }
9220
9221    @Override
9222    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9223        synchronized (this) {
9224            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9225                    "getTaskThumbnail()");
9226            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9227                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9228            if (tr != null) {
9229                return tr.getTaskThumbnailLocked();
9230            }
9231        }
9232        return null;
9233    }
9234
9235    @Override
9236    public int addAppTask(IBinder activityToken, Intent intent,
9237            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9238        final int callingUid = Binder.getCallingUid();
9239        final long callingIdent = Binder.clearCallingIdentity();
9240
9241        try {
9242            synchronized (this) {
9243                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9244                if (r == null) {
9245                    throw new IllegalArgumentException("Activity does not exist; token="
9246                            + activityToken);
9247                }
9248                ComponentName comp = intent.getComponent();
9249                if (comp == null) {
9250                    throw new IllegalArgumentException("Intent " + intent
9251                            + " must specify explicit component");
9252                }
9253                if (thumbnail.getWidth() != mThumbnailWidth
9254                        || thumbnail.getHeight() != mThumbnailHeight) {
9255                    throw new IllegalArgumentException("Bad thumbnail size: got "
9256                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9257                            + mThumbnailWidth + "x" + mThumbnailHeight);
9258                }
9259                if (intent.getSelector() != null) {
9260                    intent.setSelector(null);
9261                }
9262                if (intent.getSourceBounds() != null) {
9263                    intent.setSourceBounds(null);
9264                }
9265                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9266                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9267                        // The caller has added this as an auto-remove task...  that makes no
9268                        // sense, so turn off auto-remove.
9269                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9270                    }
9271                }
9272                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9273                    mLastAddedTaskActivity = null;
9274                }
9275                ActivityInfo ainfo = mLastAddedTaskActivity;
9276                if (ainfo == null) {
9277                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9278                            comp, 0, UserHandle.getUserId(callingUid));
9279                    if (ainfo.applicationInfo.uid != callingUid) {
9280                        throw new SecurityException(
9281                                "Can't add task for another application: target uid="
9282                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9283                    }
9284                }
9285
9286                // Use the full screen as the context for the task thumbnail
9287                final Point displaySize = new Point();
9288                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9289                r.task.stack.getDisplaySize(displaySize);
9290                thumbnailInfo.taskWidth = displaySize.x;
9291                thumbnailInfo.taskHeight = displaySize.y;
9292                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9293
9294                TaskRecord task = new TaskRecord(this,
9295                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9296                        ainfo, intent, description, thumbnailInfo);
9297
9298                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9299                if (trimIdx >= 0) {
9300                    // If this would have caused a trim, then we'll abort because that
9301                    // means it would be added at the end of the list but then just removed.
9302                    return INVALID_TASK_ID;
9303                }
9304
9305                final int N = mRecentTasks.size();
9306                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9307                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9308                    tr.removedFromRecents();
9309                }
9310
9311                task.inRecents = true;
9312                mRecentTasks.add(task);
9313                r.task.stack.addTask(task, false, "addAppTask");
9314
9315                task.setLastThumbnailLocked(thumbnail);
9316                task.freeLastThumbnail();
9317
9318                return task.taskId;
9319            }
9320        } finally {
9321            Binder.restoreCallingIdentity(callingIdent);
9322        }
9323    }
9324
9325    @Override
9326    public Point getAppTaskThumbnailSize() {
9327        synchronized (this) {
9328            return new Point(mThumbnailWidth,  mThumbnailHeight);
9329        }
9330    }
9331
9332    @Override
9333    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9334        synchronized (this) {
9335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9336            if (r != null) {
9337                r.setTaskDescription(td);
9338                r.task.updateTaskDescription();
9339            }
9340        }
9341    }
9342
9343    @Override
9344    public void setTaskResizeable(int taskId, int resizeableMode) {
9345        synchronized (this) {
9346            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9347                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9348            if (task == null) {
9349                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9350                return;
9351            }
9352            if (task.mResizeMode != resizeableMode) {
9353                task.mResizeMode = resizeableMode;
9354                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9355                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9356                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9357            }
9358        }
9359    }
9360
9361    @Override
9362    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9363        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9364        long ident = Binder.clearCallingIdentity();
9365        try {
9366            synchronized (this) {
9367                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9368                if (task == null) {
9369                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9370                    return;
9371                }
9372                int stackId = task.stack.mStackId;
9373                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9374                // in crop windows resize mode or if the task size is affected by the docked stack
9375                // changing size. No need to update configuration.
9376                if (bounds != null && task.inCropWindowsResizeMode()
9377                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9378                    mWindowManager.scrollTask(task.taskId, bounds);
9379                    return;
9380                }
9381
9382                // Place the task in the right stack if it isn't there already based on
9383                // the requested bounds.
9384                // The stack transition logic is:
9385                // - a null bounds on a freeform task moves that task to fullscreen
9386                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9387                //   that task to freeform
9388                // - otherwise the task is not moved
9389                if (!StackId.isTaskResizeAllowed(stackId)) {
9390                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9391                }
9392                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9393                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9394                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9395                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9396                }
9397                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9398                if (stackId != task.stack.mStackId) {
9399                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9400                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9401                    preserveWindow = false;
9402                }
9403
9404                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9405                        false /* deferResume */);
9406            }
9407        } finally {
9408            Binder.restoreCallingIdentity(ident);
9409        }
9410    }
9411
9412    @Override
9413    public Rect getTaskBounds(int taskId) {
9414        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9415        long ident = Binder.clearCallingIdentity();
9416        Rect rect = new Rect();
9417        try {
9418            synchronized (this) {
9419                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9420                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9421                if (task == null) {
9422                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9423                    return rect;
9424                }
9425                if (task.stack != null) {
9426                    // Return the bounds from window manager since it will be adjusted for various
9427                    // things like the presense of a docked stack for tasks that aren't resizeable.
9428                    mWindowManager.getTaskBounds(task.taskId, rect);
9429                } else {
9430                    // Task isn't in window manager yet since it isn't associated with a stack.
9431                    // Return the persist value from activity manager
9432                    if (task.mBounds != null) {
9433                        rect.set(task.mBounds);
9434                    } else if (task.mLastNonFullscreenBounds != null) {
9435                        rect.set(task.mLastNonFullscreenBounds);
9436                    }
9437                }
9438            }
9439        } finally {
9440            Binder.restoreCallingIdentity(ident);
9441        }
9442        return rect;
9443    }
9444
9445    @Override
9446    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9447        if (userId != UserHandle.getCallingUserId()) {
9448            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9449                    "getTaskDescriptionIcon");
9450        }
9451        final File passedIconFile = new File(filePath);
9452        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9453                passedIconFile.getName());
9454        if (!legitIconFile.getPath().equals(filePath)
9455                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9456            throw new IllegalArgumentException("Bad file path: " + filePath
9457                    + " passed for userId " + userId);
9458        }
9459        return mRecentTasks.getTaskDescriptionIcon(filePath);
9460    }
9461
9462    @Override
9463    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9464            throws RemoteException {
9465        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9466                opts.getCustomInPlaceResId() == 0) {
9467            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9468                    "with valid animation");
9469        }
9470        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9471        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9472                opts.getCustomInPlaceResId());
9473        mWindowManager.executeAppTransition();
9474    }
9475
9476    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9477            boolean removeFromRecents) {
9478        if (removeFromRecents) {
9479            mRecentTasks.remove(tr);
9480            tr.removedFromRecents();
9481        }
9482        ComponentName component = tr.getBaseIntent().getComponent();
9483        if (component == null) {
9484            Slog.w(TAG, "No component for base intent of task: " + tr);
9485            return;
9486        }
9487
9488        // Find any running services associated with this app and stop if needed.
9489        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9490
9491        if (!killProcess) {
9492            return;
9493        }
9494
9495        // Determine if the process(es) for this task should be killed.
9496        final String pkg = component.getPackageName();
9497        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9498        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9499        for (int i = 0; i < pmap.size(); i++) {
9500
9501            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9502            for (int j = 0; j < uids.size(); j++) {
9503                ProcessRecord proc = uids.valueAt(j);
9504                if (proc.userId != tr.userId) {
9505                    // Don't kill process for a different user.
9506                    continue;
9507                }
9508                if (proc == mHomeProcess) {
9509                    // Don't kill the home process along with tasks from the same package.
9510                    continue;
9511                }
9512                if (!proc.pkgList.containsKey(pkg)) {
9513                    // Don't kill process that is not associated with this task.
9514                    continue;
9515                }
9516
9517                for (int k = 0; k < proc.activities.size(); k++) {
9518                    TaskRecord otherTask = proc.activities.get(k).task;
9519                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9520                        // Don't kill process(es) that has an activity in a different task that is
9521                        // also in recents.
9522                        return;
9523                    }
9524                }
9525
9526                if (proc.foregroundServices) {
9527                    // Don't kill process(es) with foreground service.
9528                    return;
9529                }
9530
9531                // Add process to kill list.
9532                procsToKill.add(proc);
9533            }
9534        }
9535
9536        // Kill the running processes.
9537        for (int i = 0; i < procsToKill.size(); i++) {
9538            ProcessRecord pr = procsToKill.get(i);
9539            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9540                    && pr.curReceiver == null) {
9541                pr.kill("remove task", true);
9542            } else {
9543                // We delay killing processes that are not in the background or running a receiver.
9544                pr.waitingToKill = "remove task";
9545            }
9546        }
9547    }
9548
9549    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9550        // Remove all tasks with activities in the specified package from the list of recent tasks
9551        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9552            TaskRecord tr = mRecentTasks.get(i);
9553            if (tr.userId != userId) continue;
9554
9555            ComponentName cn = tr.intent.getComponent();
9556            if (cn != null && cn.getPackageName().equals(packageName)) {
9557                // If the package name matches, remove the task.
9558                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9559            }
9560        }
9561    }
9562
9563    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9564            int userId) {
9565
9566        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9567            TaskRecord tr = mRecentTasks.get(i);
9568            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9569                continue;
9570            }
9571
9572            ComponentName cn = tr.intent.getComponent();
9573            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9574                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9575            if (sameComponent) {
9576                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9577            }
9578        }
9579    }
9580
9581    /**
9582     * Removes the task with the specified task id.
9583     *
9584     * @param taskId Identifier of the task to be removed.
9585     * @param killProcess Kill any process associated with the task if possible.
9586     * @param removeFromRecents Whether to also remove the task from recents.
9587     * @return Returns true if the given task was found and removed.
9588     */
9589    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9590            boolean removeFromRecents) {
9591        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9592                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9593        if (tr != null) {
9594            tr.removeTaskActivitiesLocked();
9595            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9596            if (tr.isPersistable) {
9597                notifyTaskPersisterLocked(null, true);
9598            }
9599            return true;
9600        }
9601        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9602        return false;
9603    }
9604
9605    @Override
9606    public void removeStack(int stackId) {
9607        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9608        if (stackId == HOME_STACK_ID) {
9609            throw new IllegalArgumentException("Removing home stack is not allowed.");
9610        }
9611
9612        synchronized (this) {
9613            final long ident = Binder.clearCallingIdentity();
9614            try {
9615                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9616                if (stack == null) {
9617                    return;
9618                }
9619                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9620                for (int i = tasks.size() - 1; i >= 0; i--) {
9621                    removeTaskByIdLocked(
9622                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9623                }
9624            } finally {
9625                Binder.restoreCallingIdentity(ident);
9626            }
9627        }
9628    }
9629
9630    @Override
9631    public boolean removeTask(int taskId) {
9632        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9633        synchronized (this) {
9634            final long ident = Binder.clearCallingIdentity();
9635            try {
9636                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9637            } finally {
9638                Binder.restoreCallingIdentity(ident);
9639            }
9640        }
9641    }
9642
9643    /**
9644     * TODO: Add mController hook
9645     */
9646    @Override
9647    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9648        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9649
9650        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9651        synchronized(this) {
9652            moveTaskToFrontLocked(taskId, flags, bOptions);
9653        }
9654    }
9655
9656    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9657        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9658
9659        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9660                Binder.getCallingUid(), -1, -1, "Task to front")) {
9661            ActivityOptions.abort(options);
9662            return;
9663        }
9664        final long origId = Binder.clearCallingIdentity();
9665        try {
9666            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9667            if (task == null) {
9668                Slog.d(TAG, "Could not find task for id: "+ taskId);
9669                return;
9670            }
9671            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9672                mStackSupervisor.showLockTaskToast();
9673                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9674                return;
9675            }
9676            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9677            if (prev != null && prev.isRecentsActivity()) {
9678                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9679            }
9680            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9681                    false /* forceNonResizable */);
9682        } finally {
9683            Binder.restoreCallingIdentity(origId);
9684        }
9685        ActivityOptions.abort(options);
9686    }
9687
9688    /**
9689     * Moves an activity, and all of the other activities within the same task, to the bottom
9690     * of the history stack.  The activity's order within the task is unchanged.
9691     *
9692     * @param token A reference to the activity we wish to move
9693     * @param nonRoot If false then this only works if the activity is the root
9694     *                of a task; if true it will work for any activity in a task.
9695     * @return Returns true if the move completed, false if not.
9696     */
9697    @Override
9698    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9699        enforceNotIsolatedCaller("moveActivityTaskToBack");
9700        synchronized(this) {
9701            final long origId = Binder.clearCallingIdentity();
9702            try {
9703                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9704                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9705                if (task != null) {
9706                    if (mStackSupervisor.isLockedTask(task)) {
9707                        mStackSupervisor.showLockTaskToast();
9708                        return false;
9709                    }
9710                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9711                }
9712            } finally {
9713                Binder.restoreCallingIdentity(origId);
9714            }
9715        }
9716        return false;
9717    }
9718
9719    @Override
9720    public void moveTaskBackwards(int task) {
9721        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9722                "moveTaskBackwards()");
9723
9724        synchronized(this) {
9725            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9726                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9727                return;
9728            }
9729            final long origId = Binder.clearCallingIdentity();
9730            moveTaskBackwardsLocked(task);
9731            Binder.restoreCallingIdentity(origId);
9732        }
9733    }
9734
9735    private final void moveTaskBackwardsLocked(int task) {
9736        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9737    }
9738
9739    @Override
9740    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9741            IActivityContainerCallback callback) throws RemoteException {
9742        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9743        synchronized (this) {
9744            if (parentActivityToken == null) {
9745                throw new IllegalArgumentException("parent token must not be null");
9746            }
9747            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9748            if (r == null) {
9749                return null;
9750            }
9751            if (callback == null) {
9752                throw new IllegalArgumentException("callback must not be null");
9753            }
9754            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9755        }
9756    }
9757
9758    @Override
9759    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9760        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9761        synchronized (this) {
9762            mStackSupervisor.deleteActivityContainer(container);
9763        }
9764    }
9765
9766    @Override
9767    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9768        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9769        synchronized (this) {
9770            final int stackId = mStackSupervisor.getNextStackId();
9771            final ActivityStack stack =
9772                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9773            if (stack == null) {
9774                return null;
9775            }
9776            return stack.mActivityContainer;
9777        }
9778    }
9779
9780    @Override
9781    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9782        synchronized (this) {
9783            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9784            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9785                return stack.mActivityContainer.getDisplayId();
9786            }
9787            return Display.DEFAULT_DISPLAY;
9788        }
9789    }
9790
9791    @Override
9792    public int getActivityStackId(IBinder token) throws RemoteException {
9793        synchronized (this) {
9794            ActivityStack stack = ActivityRecord.getStackLocked(token);
9795            if (stack == null) {
9796                return INVALID_STACK_ID;
9797            }
9798            return stack.mStackId;
9799        }
9800    }
9801
9802    @Override
9803    public void exitFreeformMode(IBinder token) throws RemoteException {
9804        synchronized (this) {
9805            long ident = Binder.clearCallingIdentity();
9806            try {
9807                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9808                if (r == null) {
9809                    throw new IllegalArgumentException(
9810                            "exitFreeformMode: No activity record matching token=" + token);
9811                }
9812                final ActivityStack stack = r.getStackLocked(token);
9813                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9814                    throw new IllegalStateException(
9815                            "exitFreeformMode: You can only go fullscreen from freeform.");
9816                }
9817                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9818                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9819                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9820            } finally {
9821                Binder.restoreCallingIdentity(ident);
9822            }
9823        }
9824    }
9825
9826    @Override
9827    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9828        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9829        if (stackId == HOME_STACK_ID) {
9830            throw new IllegalArgumentException(
9831                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9832        }
9833        synchronized (this) {
9834            long ident = Binder.clearCallingIdentity();
9835            try {
9836                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9837                        + " to stackId=" + stackId + " toTop=" + toTop);
9838                if (stackId == DOCKED_STACK_ID) {
9839                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9840                            null /* initialBounds */);
9841                }
9842                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9843                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9844                if (result && stackId == DOCKED_STACK_ID) {
9845                    // If task moved to docked stack - show recents if needed.
9846                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9847                            "moveTaskToDockedStack");
9848                }
9849            } finally {
9850                Binder.restoreCallingIdentity(ident);
9851            }
9852        }
9853    }
9854
9855    @Override
9856    public void swapDockedAndFullscreenStack() throws RemoteException {
9857        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9858        synchronized (this) {
9859            long ident = Binder.clearCallingIdentity();
9860            try {
9861                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9862                        FULLSCREEN_WORKSPACE_STACK_ID);
9863                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9864                        : null;
9865                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9866                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9867                        : null;
9868                if (topTask == null || tasks == null || tasks.size() == 0) {
9869                    Slog.w(TAG,
9870                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9871                    return;
9872                }
9873
9874                // TODO: App transition
9875                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9876
9877                // Defer the resume so resume/pausing while moving stacks is dangerous.
9878                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9879                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9880                        ANIMATE, true /* deferResume */);
9881                final int size = tasks.size();
9882                for (int i = 0; i < size; i++) {
9883                    final int id = tasks.get(i).taskId;
9884                    if (id == topTask.taskId) {
9885                        continue;
9886                    }
9887                    mStackSupervisor.moveTaskToStackLocked(id,
9888                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9889                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9890                }
9891
9892                // Because we deferred the resume, to avoid conflicts with stack switches while
9893                // resuming, we need to do it after all the tasks are moved.
9894                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9895                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9896
9897                mWindowManager.executeAppTransition();
9898            } finally {
9899                Binder.restoreCallingIdentity(ident);
9900            }
9901        }
9902    }
9903
9904    /**
9905     * Moves the input task to the docked stack.
9906     *
9907     * @param taskId Id of task to move.
9908     * @param createMode The mode the docked stack should be created in if it doesn't exist
9909     *                   already. See
9910     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9911     *                   and
9912     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9913     * @param toTop If the task and stack should be moved to the top.
9914     * @param animate Whether we should play an animation for the moving the task
9915     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9916     *                      docked stack. Pass {@code null} to use default bounds.
9917     */
9918    @Override
9919    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9920            Rect initialBounds, boolean moveHomeStackFront) {
9921        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9922        synchronized (this) {
9923            long ident = Binder.clearCallingIdentity();
9924            try {
9925                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9926                        + " to createMode=" + createMode + " toTop=" + toTop);
9927                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9928                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9929                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9930                        animate, DEFER_RESUME);
9931                if (moved) {
9932                    if (moveHomeStackFront) {
9933                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9934                    }
9935                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9936                }
9937                return moved;
9938            } finally {
9939                Binder.restoreCallingIdentity(ident);
9940            }
9941        }
9942    }
9943
9944    /**
9945     * Moves the top activity in the input stackId to the pinned stack.
9946     *
9947     * @param stackId Id of stack to move the top activity to pinned stack.
9948     * @param bounds Bounds to use for pinned stack.
9949     *
9950     * @return True if the top activity of the input stack was successfully moved to the pinned
9951     *          stack.
9952     */
9953    @Override
9954    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9955        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9956        synchronized (this) {
9957            if (!mSupportsPictureInPicture) {
9958                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9959                        + "Device doesn't support picture-in-pciture mode");
9960            }
9961
9962            long ident = Binder.clearCallingIdentity();
9963            try {
9964                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9965            } finally {
9966                Binder.restoreCallingIdentity(ident);
9967            }
9968        }
9969    }
9970
9971    @Override
9972    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9973            boolean preserveWindows, boolean animate, int animationDuration) {
9974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9975        long ident = Binder.clearCallingIdentity();
9976        try {
9977            synchronized (this) {
9978                if (animate) {
9979                    if (stackId == PINNED_STACK_ID) {
9980                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9981                    } else {
9982                        throw new IllegalArgumentException("Stack: " + stackId
9983                                + " doesn't support animated resize.");
9984                    }
9985                } else {
9986                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9987                            null /* tempTaskInsetBounds */, preserveWindows,
9988                            allowResizeInDockedMode, !DEFER_RESUME);
9989                }
9990            }
9991        } finally {
9992            Binder.restoreCallingIdentity(ident);
9993        }
9994    }
9995
9996    @Override
9997    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9998            Rect tempDockedTaskInsetBounds,
9999            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10000        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10001                "resizeDockedStack()");
10002        long ident = Binder.clearCallingIdentity();
10003        try {
10004            synchronized (this) {
10005                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10006                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10007                        PRESERVE_WINDOWS);
10008            }
10009        } finally {
10010            Binder.restoreCallingIdentity(ident);
10011        }
10012    }
10013
10014    @Override
10015    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10016        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10017                "resizePinnedStack()");
10018        final long ident = Binder.clearCallingIdentity();
10019        try {
10020            synchronized (this) {
10021                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10022            }
10023        } finally {
10024            Binder.restoreCallingIdentity(ident);
10025        }
10026    }
10027
10028    @Override
10029    public void positionTaskInStack(int taskId, int stackId, int position) {
10030        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10031        if (stackId == HOME_STACK_ID) {
10032            throw new IllegalArgumentException(
10033                    "positionTaskInStack: Attempt to change the position of task "
10034                    + taskId + " in/to home stack");
10035        }
10036        synchronized (this) {
10037            long ident = Binder.clearCallingIdentity();
10038            try {
10039                if (DEBUG_STACK) Slog.d(TAG_STACK,
10040                        "positionTaskInStack: positioning task=" + taskId
10041                        + " in stackId=" + stackId + " at position=" + position);
10042                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10043            } finally {
10044                Binder.restoreCallingIdentity(ident);
10045            }
10046        }
10047    }
10048
10049    @Override
10050    public List<StackInfo> getAllStackInfos() {
10051        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10052        long ident = Binder.clearCallingIdentity();
10053        try {
10054            synchronized (this) {
10055                return mStackSupervisor.getAllStackInfosLocked();
10056            }
10057        } finally {
10058            Binder.restoreCallingIdentity(ident);
10059        }
10060    }
10061
10062    @Override
10063    public StackInfo getStackInfo(int stackId) {
10064        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10065        long ident = Binder.clearCallingIdentity();
10066        try {
10067            synchronized (this) {
10068                return mStackSupervisor.getStackInfoLocked(stackId);
10069            }
10070        } finally {
10071            Binder.restoreCallingIdentity(ident);
10072        }
10073    }
10074
10075    @Override
10076    public boolean isInHomeStack(int taskId) {
10077        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10078        long ident = Binder.clearCallingIdentity();
10079        try {
10080            synchronized (this) {
10081                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10082                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10083                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10084            }
10085        } finally {
10086            Binder.restoreCallingIdentity(ident);
10087        }
10088    }
10089
10090    @Override
10091    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10092        synchronized(this) {
10093            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10094        }
10095    }
10096
10097    @Override
10098    public void updateDeviceOwner(String packageName) {
10099        final int callingUid = Binder.getCallingUid();
10100        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10101            throw new SecurityException("updateDeviceOwner called from non-system process");
10102        }
10103        synchronized (this) {
10104            mDeviceOwnerName = packageName;
10105        }
10106    }
10107
10108    @Override
10109    public void updateLockTaskPackages(int userId, String[] packages) {
10110        final int callingUid = Binder.getCallingUid();
10111        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10112            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10113                    "updateLockTaskPackages()");
10114        }
10115        synchronized (this) {
10116            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10117                    Arrays.toString(packages));
10118            mLockTaskPackages.put(userId, packages);
10119            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10120        }
10121    }
10122
10123
10124    void startLockTaskModeLocked(TaskRecord task) {
10125        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10126        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10127            return;
10128        }
10129
10130        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10131        // is initiated by system after the pinning request was shown and locked mode is initiated
10132        // by an authorized app directly
10133        final int callingUid = Binder.getCallingUid();
10134        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10135        long ident = Binder.clearCallingIdentity();
10136        try {
10137            if (!isSystemInitiated) {
10138                task.mLockTaskUid = callingUid;
10139                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10140                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10141                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10142                    StatusBarManagerInternal statusBarManager =
10143                            LocalServices.getService(StatusBarManagerInternal.class);
10144                    if (statusBarManager != null) {
10145                        statusBarManager.showScreenPinningRequest(task.taskId);
10146                    }
10147                    return;
10148                }
10149
10150                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10151                if (stack == null || task != stack.topTask()) {
10152                    throw new IllegalArgumentException("Invalid task, not in foreground");
10153                }
10154            }
10155            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10156                    "Locking fully");
10157            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10158                    ActivityManager.LOCK_TASK_MODE_PINNED :
10159                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10160                    "startLockTask", true);
10161        } finally {
10162            Binder.restoreCallingIdentity(ident);
10163        }
10164    }
10165
10166    @Override
10167    public void startLockTaskMode(int taskId) {
10168        synchronized (this) {
10169            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10170            if (task != null) {
10171                startLockTaskModeLocked(task);
10172            }
10173        }
10174    }
10175
10176    @Override
10177    public void startLockTaskMode(IBinder token) {
10178        synchronized (this) {
10179            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10180            if (r == null) {
10181                return;
10182            }
10183            final TaskRecord task = r.task;
10184            if (task != null) {
10185                startLockTaskModeLocked(task);
10186            }
10187        }
10188    }
10189
10190    @Override
10191    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10192        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10193        // This makes inner call to look as if it was initiated by system.
10194        long ident = Binder.clearCallingIdentity();
10195        try {
10196            synchronized (this) {
10197                startLockTaskMode(taskId);
10198            }
10199        } finally {
10200            Binder.restoreCallingIdentity(ident);
10201        }
10202    }
10203
10204    @Override
10205    public void stopLockTaskMode() {
10206        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10207        if (lockTask == null) {
10208            // Our work here is done.
10209            return;
10210        }
10211
10212        final int callingUid = Binder.getCallingUid();
10213        final int lockTaskUid = lockTask.mLockTaskUid;
10214        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10215        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10216            // Done.
10217            return;
10218        } else {
10219            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10220            // It is possible lockTaskMode was started by the system process because
10221            // android:lockTaskMode is set to a locking value in the application manifest
10222            // instead of the app calling startLockTaskMode. In this case
10223            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10224            // {@link TaskRecord.effectiveUid} instead. Also caller with
10225            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10226            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10227                    && callingUid != lockTaskUid
10228                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10229                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10230                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10231            }
10232        }
10233        long ident = Binder.clearCallingIdentity();
10234        try {
10235            Log.d(TAG, "stopLockTaskMode");
10236            // Stop lock task
10237            synchronized (this) {
10238                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10239                        "stopLockTask", true);
10240            }
10241            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10242            if (tm != null) {
10243                tm.showInCallScreen(false);
10244            }
10245        } finally {
10246            Binder.restoreCallingIdentity(ident);
10247        }
10248    }
10249
10250    /**
10251     * This API should be called by SystemUI only when user perform certain action to dismiss
10252     * lock task mode. We should only dismiss pinned lock task mode in this case.
10253     */
10254    @Override
10255    public void stopSystemLockTaskMode() throws RemoteException {
10256        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10257            stopLockTaskMode();
10258        } else {
10259            mStackSupervisor.showLockTaskToast();
10260        }
10261    }
10262
10263    @Override
10264    public boolean isInLockTaskMode() {
10265        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10266    }
10267
10268    @Override
10269    public int getLockTaskModeState() {
10270        synchronized (this) {
10271            return mStackSupervisor.getLockTaskModeState();
10272        }
10273    }
10274
10275    @Override
10276    public void showLockTaskEscapeMessage(IBinder token) {
10277        synchronized (this) {
10278            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10279            if (r == null) {
10280                return;
10281            }
10282            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10283        }
10284    }
10285
10286    // =========================================================
10287    // CONTENT PROVIDERS
10288    // =========================================================
10289
10290    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10291        List<ProviderInfo> providers = null;
10292        try {
10293            providers = AppGlobals.getPackageManager()
10294                    .queryContentProviders(app.processName, app.uid,
10295                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10296                                    | MATCH_DEBUG_TRIAGED_MISSING)
10297                    .getList();
10298        } catch (RemoteException ex) {
10299        }
10300        if (DEBUG_MU) Slog.v(TAG_MU,
10301                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10302        int userId = app.userId;
10303        if (providers != null) {
10304            int N = providers.size();
10305            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10306            for (int i=0; i<N; i++) {
10307                // TODO: keep logic in sync with installEncryptionUnawareProviders
10308                ProviderInfo cpi =
10309                    (ProviderInfo)providers.get(i);
10310                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10311                        cpi.name, cpi.flags);
10312                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10313                    // This is a singleton provider, but a user besides the
10314                    // default user is asking to initialize a process it runs
10315                    // in...  well, no, it doesn't actually run in this process,
10316                    // it runs in the process of the default user.  Get rid of it.
10317                    providers.remove(i);
10318                    N--;
10319                    i--;
10320                    continue;
10321                }
10322
10323                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10324                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10325                if (cpr == null) {
10326                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10327                    mProviderMap.putProviderByClass(comp, cpr);
10328                }
10329                if (DEBUG_MU) Slog.v(TAG_MU,
10330                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10331                app.pubProviders.put(cpi.name, cpr);
10332                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10333                    // Don't add this if it is a platform component that is marked
10334                    // to run in multiple processes, because this is actually
10335                    // part of the framework so doesn't make sense to track as a
10336                    // separate apk in the process.
10337                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10338                            mProcessStats);
10339                }
10340                notifyPackageUse(cpi.applicationInfo.packageName,
10341                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10342            }
10343        }
10344        return providers;
10345    }
10346
10347    /**
10348     * Check if {@link ProcessRecord} has a possible chance at accessing the
10349     * given {@link ProviderInfo}. Final permission checking is always done
10350     * in {@link ContentProvider}.
10351     */
10352    private final String checkContentProviderPermissionLocked(
10353            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10354        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10355        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10356        boolean checkedGrants = false;
10357        if (checkUser) {
10358            // Looking for cross-user grants before enforcing the typical cross-users permissions
10359            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10360            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10361                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10362                    return null;
10363                }
10364                checkedGrants = true;
10365            }
10366            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10367                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10368            if (userId != tmpTargetUserId) {
10369                // When we actually went to determine the final targer user ID, this ended
10370                // up different than our initial check for the authority.  This is because
10371                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10372                // SELF.  So we need to re-check the grants again.
10373                checkedGrants = false;
10374            }
10375        }
10376        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10377                cpi.applicationInfo.uid, cpi.exported)
10378                == PackageManager.PERMISSION_GRANTED) {
10379            return null;
10380        }
10381        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10382                cpi.applicationInfo.uid, cpi.exported)
10383                == PackageManager.PERMISSION_GRANTED) {
10384            return null;
10385        }
10386
10387        PathPermission[] pps = cpi.pathPermissions;
10388        if (pps != null) {
10389            int i = pps.length;
10390            while (i > 0) {
10391                i--;
10392                PathPermission pp = pps[i];
10393                String pprperm = pp.getReadPermission();
10394                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10395                        cpi.applicationInfo.uid, cpi.exported)
10396                        == PackageManager.PERMISSION_GRANTED) {
10397                    return null;
10398                }
10399                String ppwperm = pp.getWritePermission();
10400                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10401                        cpi.applicationInfo.uid, cpi.exported)
10402                        == PackageManager.PERMISSION_GRANTED) {
10403                    return null;
10404                }
10405            }
10406        }
10407        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10408            return null;
10409        }
10410
10411        String msg;
10412        if (!cpi.exported) {
10413            msg = "Permission Denial: opening provider " + cpi.name
10414                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10415                    + ", uid=" + callingUid + ") that is not exported from uid "
10416                    + cpi.applicationInfo.uid;
10417        } else {
10418            msg = "Permission Denial: opening provider " + cpi.name
10419                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10420                    + ", uid=" + callingUid + ") requires "
10421                    + cpi.readPermission + " or " + cpi.writePermission;
10422        }
10423        Slog.w(TAG, msg);
10424        return msg;
10425    }
10426
10427    /**
10428     * Returns if the ContentProvider has granted a uri to callingUid
10429     */
10430    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10431        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10432        if (perms != null) {
10433            for (int i=perms.size()-1; i>=0; i--) {
10434                GrantUri grantUri = perms.keyAt(i);
10435                if (grantUri.sourceUserId == userId || !checkUser) {
10436                    if (matchesProvider(grantUri.uri, cpi)) {
10437                        return true;
10438                    }
10439                }
10440            }
10441        }
10442        return false;
10443    }
10444
10445    /**
10446     * Returns true if the uri authority is one of the authorities specified in the provider.
10447     */
10448    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10449        String uriAuth = uri.getAuthority();
10450        String cpiAuth = cpi.authority;
10451        if (cpiAuth.indexOf(';') == -1) {
10452            return cpiAuth.equals(uriAuth);
10453        }
10454        String[] cpiAuths = cpiAuth.split(";");
10455        int length = cpiAuths.length;
10456        for (int i = 0; i < length; i++) {
10457            if (cpiAuths[i].equals(uriAuth)) return true;
10458        }
10459        return false;
10460    }
10461
10462    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10463            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10464        if (r != null) {
10465            for (int i=0; i<r.conProviders.size(); i++) {
10466                ContentProviderConnection conn = r.conProviders.get(i);
10467                if (conn.provider == cpr) {
10468                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10469                            "Adding provider requested by "
10470                            + r.processName + " from process "
10471                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10472                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10473                    if (stable) {
10474                        conn.stableCount++;
10475                        conn.numStableIncs++;
10476                    } else {
10477                        conn.unstableCount++;
10478                        conn.numUnstableIncs++;
10479                    }
10480                    return conn;
10481                }
10482            }
10483            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10484            if (stable) {
10485                conn.stableCount = 1;
10486                conn.numStableIncs = 1;
10487            } else {
10488                conn.unstableCount = 1;
10489                conn.numUnstableIncs = 1;
10490            }
10491            cpr.connections.add(conn);
10492            r.conProviders.add(conn);
10493            startAssociationLocked(r.uid, r.processName, r.curProcState,
10494                    cpr.uid, cpr.name, cpr.info.processName);
10495            return conn;
10496        }
10497        cpr.addExternalProcessHandleLocked(externalProcessToken);
10498        return null;
10499    }
10500
10501    boolean decProviderCountLocked(ContentProviderConnection conn,
10502            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10503        if (conn != null) {
10504            cpr = conn.provider;
10505            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10506                    "Removing provider requested by "
10507                    + conn.client.processName + " from process "
10508                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10509                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10510            if (stable) {
10511                conn.stableCount--;
10512            } else {
10513                conn.unstableCount--;
10514            }
10515            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10516                cpr.connections.remove(conn);
10517                conn.client.conProviders.remove(conn);
10518                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10519                    // The client is more important than last activity -- note the time this
10520                    // is happening, so we keep the old provider process around a bit as last
10521                    // activity to avoid thrashing it.
10522                    if (cpr.proc != null) {
10523                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10524                    }
10525                }
10526                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10527                return true;
10528            }
10529            return false;
10530        }
10531        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10532        return false;
10533    }
10534
10535    private void checkTime(long startTime, String where) {
10536        long now = SystemClock.uptimeMillis();
10537        if ((now-startTime) > 50) {
10538            // If we are taking more than 50ms, log about it.
10539            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10540        }
10541    }
10542
10543    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10544            PROC_SPACE_TERM,
10545            PROC_SPACE_TERM|PROC_PARENS,
10546            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10547    };
10548
10549    private final long[] mProcessStateStatsLongs = new long[1];
10550
10551    boolean isProcessAliveLocked(ProcessRecord proc) {
10552        if (proc.procStatFile == null) {
10553            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10554        }
10555        mProcessStateStatsLongs[0] = 0;
10556        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10557                mProcessStateStatsLongs, null)) {
10558            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10559            return false;
10560        }
10561        final long state = mProcessStateStatsLongs[0];
10562        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10563                + (char)state);
10564        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10565    }
10566
10567    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10568            String name, IBinder token, boolean stable, int userId) {
10569        ContentProviderRecord cpr;
10570        ContentProviderConnection conn = null;
10571        ProviderInfo cpi = null;
10572
10573        synchronized(this) {
10574            long startTime = SystemClock.uptimeMillis();
10575
10576            ProcessRecord r = null;
10577            if (caller != null) {
10578                r = getRecordForAppLocked(caller);
10579                if (r == null) {
10580                    throw new SecurityException(
10581                            "Unable to find app for caller " + caller
10582                          + " (pid=" + Binder.getCallingPid()
10583                          + ") when getting content provider " + name);
10584                }
10585            }
10586
10587            boolean checkCrossUser = true;
10588
10589            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10590
10591            // First check if this content provider has been published...
10592            cpr = mProviderMap.getProviderByName(name, userId);
10593            // If that didn't work, check if it exists for user 0 and then
10594            // verify that it's a singleton provider before using it.
10595            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10596                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10597                if (cpr != null) {
10598                    cpi = cpr.info;
10599                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10600                            cpi.name, cpi.flags)
10601                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10602                        userId = UserHandle.USER_SYSTEM;
10603                        checkCrossUser = false;
10604                    } else {
10605                        cpr = null;
10606                        cpi = null;
10607                    }
10608                }
10609            }
10610
10611            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10612            if (providerRunning) {
10613                cpi = cpr.info;
10614                String msg;
10615                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10616                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10617                        != null) {
10618                    throw new SecurityException(msg);
10619                }
10620                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10621
10622                if (r != null && cpr.canRunHere(r)) {
10623                    // This provider has been published or is in the process
10624                    // of being published...  but it is also allowed to run
10625                    // in the caller's process, so don't make a connection
10626                    // and just let the caller instantiate its own instance.
10627                    ContentProviderHolder holder = cpr.newHolder(null);
10628                    // don't give caller the provider object, it needs
10629                    // to make its own.
10630                    holder.provider = null;
10631                    return holder;
10632                }
10633
10634                final long origId = Binder.clearCallingIdentity();
10635
10636                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10637
10638                // In this case the provider instance already exists, so we can
10639                // return it right away.
10640                conn = incProviderCountLocked(r, cpr, token, stable);
10641                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10642                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10643                        // If this is a perceptible app accessing the provider,
10644                        // make sure to count it as being accessed and thus
10645                        // back up on the LRU list.  This is good because
10646                        // content providers are often expensive to start.
10647                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10648                        updateLruProcessLocked(cpr.proc, false, null);
10649                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10650                    }
10651                }
10652
10653                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10654                final int verifiedAdj = cpr.proc.verifiedAdj;
10655                boolean success = updateOomAdjLocked(cpr.proc);
10656                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10657                // if the process has been successfully adjusted.  So to reduce races with
10658                // it, we will check whether the process still exists.  Note that this doesn't
10659                // completely get rid of races with LMK killing the process, but should make
10660                // them much smaller.
10661                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10662                    success = false;
10663                }
10664                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10665                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10666                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10667                // NOTE: there is still a race here where a signal could be
10668                // pending on the process even though we managed to update its
10669                // adj level.  Not sure what to do about this, but at least
10670                // the race is now smaller.
10671                if (!success) {
10672                    // Uh oh...  it looks like the provider's process
10673                    // has been killed on us.  We need to wait for a new
10674                    // process to be started, and make sure its death
10675                    // doesn't kill our process.
10676                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10677                            + " is crashing; detaching " + r);
10678                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10679                    checkTime(startTime, "getContentProviderImpl: before appDied");
10680                    appDiedLocked(cpr.proc);
10681                    checkTime(startTime, "getContentProviderImpl: after appDied");
10682                    if (!lastRef) {
10683                        // This wasn't the last ref our process had on
10684                        // the provider...  we have now been killed, bail.
10685                        return null;
10686                    }
10687                    providerRunning = false;
10688                    conn = null;
10689                } else {
10690                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10691                }
10692
10693                Binder.restoreCallingIdentity(origId);
10694            }
10695
10696            if (!providerRunning) {
10697                try {
10698                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10699                    cpi = AppGlobals.getPackageManager().
10700                        resolveContentProvider(name,
10701                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10702                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10703                } catch (RemoteException ex) {
10704                }
10705                if (cpi == null) {
10706                    return null;
10707                }
10708                // If the provider is a singleton AND
10709                // (it's a call within the same user || the provider is a
10710                // privileged app)
10711                // Then allow connecting to the singleton provider
10712                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10713                        cpi.name, cpi.flags)
10714                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10715                if (singleton) {
10716                    userId = UserHandle.USER_SYSTEM;
10717                }
10718                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10719                checkTime(startTime, "getContentProviderImpl: got app info for user");
10720
10721                String msg;
10722                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10723                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10724                        != null) {
10725                    throw new SecurityException(msg);
10726                }
10727                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10728
10729                if (!mProcessesReady
10730                        && !cpi.processName.equals("system")) {
10731                    // If this content provider does not run in the system
10732                    // process, and the system is not yet ready to run other
10733                    // processes, then fail fast instead of hanging.
10734                    throw new IllegalArgumentException(
10735                            "Attempt to launch content provider before system ready");
10736                }
10737
10738                // Make sure that the user who owns this provider is running.  If not,
10739                // we don't want to allow it to run.
10740                if (!mUserController.isUserRunningLocked(userId, 0)) {
10741                    Slog.w(TAG, "Unable to launch app "
10742                            + cpi.applicationInfo.packageName + "/"
10743                            + cpi.applicationInfo.uid + " for provider "
10744                            + name + ": user " + userId + " is stopped");
10745                    return null;
10746                }
10747
10748                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10749                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10750                cpr = mProviderMap.getProviderByClass(comp, userId);
10751                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10752                final boolean firstClass = cpr == null;
10753                if (firstClass) {
10754                    final long ident = Binder.clearCallingIdentity();
10755
10756                    // If permissions need a review before any of the app components can run,
10757                    // we return no provider and launch a review activity if the calling app
10758                    // is in the foreground.
10759                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10760                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10761                            return null;
10762                        }
10763                    }
10764
10765                    try {
10766                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10767                        ApplicationInfo ai =
10768                            AppGlobals.getPackageManager().
10769                                getApplicationInfo(
10770                                        cpi.applicationInfo.packageName,
10771                                        STOCK_PM_FLAGS, userId);
10772                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10773                        if (ai == null) {
10774                            Slog.w(TAG, "No package info for content provider "
10775                                    + cpi.name);
10776                            return null;
10777                        }
10778                        ai = getAppInfoForUser(ai, userId);
10779                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10780                    } catch (RemoteException ex) {
10781                        // pm is in same process, this will never happen.
10782                    } finally {
10783                        Binder.restoreCallingIdentity(ident);
10784                    }
10785                }
10786
10787                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10788
10789                if (r != null && cpr.canRunHere(r)) {
10790                    // If this is a multiprocess provider, then just return its
10791                    // info and allow the caller to instantiate it.  Only do
10792                    // this if the provider is the same user as the caller's
10793                    // process, or can run as root (so can be in any process).
10794                    return cpr.newHolder(null);
10795                }
10796
10797                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10798                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10799                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10800
10801                // This is single process, and our app is now connecting to it.
10802                // See if we are already in the process of launching this
10803                // provider.
10804                final int N = mLaunchingProviders.size();
10805                int i;
10806                for (i = 0; i < N; i++) {
10807                    if (mLaunchingProviders.get(i) == cpr) {
10808                        break;
10809                    }
10810                }
10811
10812                // If the provider is not already being launched, then get it
10813                // started.
10814                if (i >= N) {
10815                    final long origId = Binder.clearCallingIdentity();
10816
10817                    try {
10818                        // Content provider is now in use, its package can't be stopped.
10819                        try {
10820                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10821                            AppGlobals.getPackageManager().setPackageStoppedState(
10822                                    cpr.appInfo.packageName, false, userId);
10823                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10824                        } catch (RemoteException e) {
10825                        } catch (IllegalArgumentException e) {
10826                            Slog.w(TAG, "Failed trying to unstop package "
10827                                    + cpr.appInfo.packageName + ": " + e);
10828                        }
10829
10830                        // Use existing process if already started
10831                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10832                        ProcessRecord proc = getProcessRecordLocked(
10833                                cpi.processName, cpr.appInfo.uid, false);
10834                        if (proc != null && proc.thread != null && !proc.killed) {
10835                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10836                                    "Installing in existing process " + proc);
10837                            if (!proc.pubProviders.containsKey(cpi.name)) {
10838                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10839                                proc.pubProviders.put(cpi.name, cpr);
10840                                try {
10841                                    proc.thread.scheduleInstallProvider(cpi);
10842                                } catch (RemoteException e) {
10843                                }
10844                            }
10845                        } else {
10846                            checkTime(startTime, "getContentProviderImpl: before start process");
10847                            proc = startProcessLocked(cpi.processName,
10848                                    cpr.appInfo, false, 0, "content provider",
10849                                    new ComponentName(cpi.applicationInfo.packageName,
10850                                            cpi.name), false, false, false);
10851                            checkTime(startTime, "getContentProviderImpl: after start process");
10852                            if (proc == null) {
10853                                Slog.w(TAG, "Unable to launch app "
10854                                        + cpi.applicationInfo.packageName + "/"
10855                                        + cpi.applicationInfo.uid + " for provider "
10856                                        + name + ": process is bad");
10857                                return null;
10858                            }
10859                        }
10860                        cpr.launchingApp = proc;
10861                        mLaunchingProviders.add(cpr);
10862                    } finally {
10863                        Binder.restoreCallingIdentity(origId);
10864                    }
10865                }
10866
10867                checkTime(startTime, "getContentProviderImpl: updating data structures");
10868
10869                // Make sure the provider is published (the same provider class
10870                // may be published under multiple names).
10871                if (firstClass) {
10872                    mProviderMap.putProviderByClass(comp, cpr);
10873                }
10874
10875                mProviderMap.putProviderByName(name, cpr);
10876                conn = incProviderCountLocked(r, cpr, token, stable);
10877                if (conn != null) {
10878                    conn.waiting = true;
10879                }
10880            }
10881            checkTime(startTime, "getContentProviderImpl: done!");
10882        }
10883
10884        // Wait for the provider to be published...
10885        synchronized (cpr) {
10886            while (cpr.provider == null) {
10887                if (cpr.launchingApp == null) {
10888                    Slog.w(TAG, "Unable to launch app "
10889                            + cpi.applicationInfo.packageName + "/"
10890                            + cpi.applicationInfo.uid + " for provider "
10891                            + name + ": launching app became null");
10892                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10893                            UserHandle.getUserId(cpi.applicationInfo.uid),
10894                            cpi.applicationInfo.packageName,
10895                            cpi.applicationInfo.uid, name);
10896                    return null;
10897                }
10898                try {
10899                    if (DEBUG_MU) Slog.v(TAG_MU,
10900                            "Waiting to start provider " + cpr
10901                            + " launchingApp=" + cpr.launchingApp);
10902                    if (conn != null) {
10903                        conn.waiting = true;
10904                    }
10905                    cpr.wait();
10906                } catch (InterruptedException ex) {
10907                } finally {
10908                    if (conn != null) {
10909                        conn.waiting = false;
10910                    }
10911                }
10912            }
10913        }
10914        return cpr != null ? cpr.newHolder(conn) : null;
10915    }
10916
10917    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10918            ProcessRecord r, final int userId) {
10919        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10920                cpi.packageName, userId)) {
10921
10922            final boolean callerForeground = r == null || r.setSchedGroup
10923                    != ProcessList.SCHED_GROUP_BACKGROUND;
10924
10925            // Show a permission review UI only for starting from a foreground app
10926            if (!callerForeground) {
10927                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10928                        + cpi.packageName + " requires a permissions review");
10929                return false;
10930            }
10931
10932            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10933            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10934                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10935            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10936
10937            if (DEBUG_PERMISSIONS_REVIEW) {
10938                Slog.i(TAG, "u" + userId + " Launching permission review "
10939                        + "for package " + cpi.packageName);
10940            }
10941
10942            final UserHandle userHandle = new UserHandle(userId);
10943            mHandler.post(new Runnable() {
10944                @Override
10945                public void run() {
10946                    mContext.startActivityAsUser(intent, userHandle);
10947                }
10948            });
10949
10950            return false;
10951        }
10952
10953        return true;
10954    }
10955
10956    PackageManagerInternal getPackageManagerInternalLocked() {
10957        if (mPackageManagerInt == null) {
10958            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10959        }
10960        return mPackageManagerInt;
10961    }
10962
10963    @Override
10964    public final ContentProviderHolder getContentProvider(
10965            IApplicationThread caller, String name, int userId, boolean stable) {
10966        enforceNotIsolatedCaller("getContentProvider");
10967        if (caller == null) {
10968            String msg = "null IApplicationThread when getting content provider "
10969                    + name;
10970            Slog.w(TAG, msg);
10971            throw new SecurityException(msg);
10972        }
10973        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10974        // with cross-user grant.
10975        return getContentProviderImpl(caller, name, null, stable, userId);
10976    }
10977
10978    public ContentProviderHolder getContentProviderExternal(
10979            String name, int userId, IBinder token) {
10980        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10981            "Do not have permission in call getContentProviderExternal()");
10982        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10983                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10984        return getContentProviderExternalUnchecked(name, token, userId);
10985    }
10986
10987    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10988            IBinder token, int userId) {
10989        return getContentProviderImpl(null, name, token, true, userId);
10990    }
10991
10992    /**
10993     * Drop a content provider from a ProcessRecord's bookkeeping
10994     */
10995    public void removeContentProvider(IBinder connection, boolean stable) {
10996        enforceNotIsolatedCaller("removeContentProvider");
10997        long ident = Binder.clearCallingIdentity();
10998        try {
10999            synchronized (this) {
11000                ContentProviderConnection conn;
11001                try {
11002                    conn = (ContentProviderConnection)connection;
11003                } catch (ClassCastException e) {
11004                    String msg ="removeContentProvider: " + connection
11005                            + " not a ContentProviderConnection";
11006                    Slog.w(TAG, msg);
11007                    throw new IllegalArgumentException(msg);
11008                }
11009                if (conn == null) {
11010                    throw new NullPointerException("connection is null");
11011                }
11012                if (decProviderCountLocked(conn, null, null, stable)) {
11013                    updateOomAdjLocked();
11014                }
11015            }
11016        } finally {
11017            Binder.restoreCallingIdentity(ident);
11018        }
11019    }
11020
11021    public void removeContentProviderExternal(String name, IBinder token) {
11022        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11023            "Do not have permission in call removeContentProviderExternal()");
11024        int userId = UserHandle.getCallingUserId();
11025        long ident = Binder.clearCallingIdentity();
11026        try {
11027            removeContentProviderExternalUnchecked(name, token, userId);
11028        } finally {
11029            Binder.restoreCallingIdentity(ident);
11030        }
11031    }
11032
11033    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11034        synchronized (this) {
11035            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11036            if(cpr == null) {
11037                //remove from mProvidersByClass
11038                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11039                return;
11040            }
11041
11042            //update content provider record entry info
11043            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11044            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11045            if (localCpr.hasExternalProcessHandles()) {
11046                if (localCpr.removeExternalProcessHandleLocked(token)) {
11047                    updateOomAdjLocked();
11048                } else {
11049                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11050                            + " with no external reference for token: "
11051                            + token + ".");
11052                }
11053            } else {
11054                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11055                        + " with no external references.");
11056            }
11057        }
11058    }
11059
11060    public final void publishContentProviders(IApplicationThread caller,
11061            List<ContentProviderHolder> providers) {
11062        if (providers == null) {
11063            return;
11064        }
11065
11066        enforceNotIsolatedCaller("publishContentProviders");
11067        synchronized (this) {
11068            final ProcessRecord r = getRecordForAppLocked(caller);
11069            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11070            if (r == null) {
11071                throw new SecurityException(
11072                        "Unable to find app for caller " + caller
11073                      + " (pid=" + Binder.getCallingPid()
11074                      + ") when publishing content providers");
11075            }
11076
11077            final long origId = Binder.clearCallingIdentity();
11078
11079            final int N = providers.size();
11080            for (int i = 0; i < N; i++) {
11081                ContentProviderHolder src = providers.get(i);
11082                if (src == null || src.info == null || src.provider == null) {
11083                    continue;
11084                }
11085                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11086                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11087                if (dst != null) {
11088                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11089                    mProviderMap.putProviderByClass(comp, dst);
11090                    String names[] = dst.info.authority.split(";");
11091                    for (int j = 0; j < names.length; j++) {
11092                        mProviderMap.putProviderByName(names[j], dst);
11093                    }
11094
11095                    int launchingCount = mLaunchingProviders.size();
11096                    int j;
11097                    boolean wasInLaunchingProviders = false;
11098                    for (j = 0; j < launchingCount; j++) {
11099                        if (mLaunchingProviders.get(j) == dst) {
11100                            mLaunchingProviders.remove(j);
11101                            wasInLaunchingProviders = true;
11102                            j--;
11103                            launchingCount--;
11104                        }
11105                    }
11106                    if (wasInLaunchingProviders) {
11107                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11108                    }
11109                    synchronized (dst) {
11110                        dst.provider = src.provider;
11111                        dst.proc = r;
11112                        dst.notifyAll();
11113                    }
11114                    updateOomAdjLocked(r);
11115                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11116                            src.info.authority);
11117                }
11118            }
11119
11120            Binder.restoreCallingIdentity(origId);
11121        }
11122    }
11123
11124    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11125        ContentProviderConnection conn;
11126        try {
11127            conn = (ContentProviderConnection)connection;
11128        } catch (ClassCastException e) {
11129            String msg ="refContentProvider: " + connection
11130                    + " not a ContentProviderConnection";
11131            Slog.w(TAG, msg);
11132            throw new IllegalArgumentException(msg);
11133        }
11134        if (conn == null) {
11135            throw new NullPointerException("connection is null");
11136        }
11137
11138        synchronized (this) {
11139            if (stable > 0) {
11140                conn.numStableIncs += stable;
11141            }
11142            stable = conn.stableCount + stable;
11143            if (stable < 0) {
11144                throw new IllegalStateException("stableCount < 0: " + stable);
11145            }
11146
11147            if (unstable > 0) {
11148                conn.numUnstableIncs += unstable;
11149            }
11150            unstable = conn.unstableCount + unstable;
11151            if (unstable < 0) {
11152                throw new IllegalStateException("unstableCount < 0: " + unstable);
11153            }
11154
11155            if ((stable+unstable) <= 0) {
11156                throw new IllegalStateException("ref counts can't go to zero here: stable="
11157                        + stable + " unstable=" + unstable);
11158            }
11159            conn.stableCount = stable;
11160            conn.unstableCount = unstable;
11161            return !conn.dead;
11162        }
11163    }
11164
11165    public void unstableProviderDied(IBinder connection) {
11166        ContentProviderConnection conn;
11167        try {
11168            conn = (ContentProviderConnection)connection;
11169        } catch (ClassCastException e) {
11170            String msg ="refContentProvider: " + connection
11171                    + " not a ContentProviderConnection";
11172            Slog.w(TAG, msg);
11173            throw new IllegalArgumentException(msg);
11174        }
11175        if (conn == null) {
11176            throw new NullPointerException("connection is null");
11177        }
11178
11179        // Safely retrieve the content provider associated with the connection.
11180        IContentProvider provider;
11181        synchronized (this) {
11182            provider = conn.provider.provider;
11183        }
11184
11185        if (provider == null) {
11186            // Um, yeah, we're way ahead of you.
11187            return;
11188        }
11189
11190        // Make sure the caller is being honest with us.
11191        if (provider.asBinder().pingBinder()) {
11192            // Er, no, still looks good to us.
11193            synchronized (this) {
11194                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11195                        + " says " + conn + " died, but we don't agree");
11196                return;
11197            }
11198        }
11199
11200        // Well look at that!  It's dead!
11201        synchronized (this) {
11202            if (conn.provider.provider != provider) {
11203                // But something changed...  good enough.
11204                return;
11205            }
11206
11207            ProcessRecord proc = conn.provider.proc;
11208            if (proc == null || proc.thread == null) {
11209                // Seems like the process is already cleaned up.
11210                return;
11211            }
11212
11213            // As far as we're concerned, this is just like receiving a
11214            // death notification...  just a bit prematurely.
11215            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11216                    + ") early provider death");
11217            final long ident = Binder.clearCallingIdentity();
11218            try {
11219                appDiedLocked(proc);
11220            } finally {
11221                Binder.restoreCallingIdentity(ident);
11222            }
11223        }
11224    }
11225
11226    @Override
11227    public void appNotRespondingViaProvider(IBinder connection) {
11228        enforceCallingPermission(
11229                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11230
11231        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11232        if (conn == null) {
11233            Slog.w(TAG, "ContentProviderConnection is null");
11234            return;
11235        }
11236
11237        final ProcessRecord host = conn.provider.proc;
11238        if (host == null) {
11239            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11240            return;
11241        }
11242
11243        mHandler.post(new Runnable() {
11244            @Override
11245            public void run() {
11246                mAppErrors.appNotResponding(host, null, null, false,
11247                        "ContentProvider not responding");
11248            }
11249        });
11250    }
11251
11252    public final void installSystemProviders() {
11253        List<ProviderInfo> providers;
11254        synchronized (this) {
11255            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11256            providers = generateApplicationProvidersLocked(app);
11257            if (providers != null) {
11258                for (int i=providers.size()-1; i>=0; i--) {
11259                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11260                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11261                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11262                                + ": not system .apk");
11263                        providers.remove(i);
11264                    }
11265                }
11266            }
11267        }
11268        if (providers != null) {
11269            mSystemThread.installSystemProviders(providers);
11270        }
11271
11272        mCoreSettingsObserver = new CoreSettingsObserver(this);
11273        mFontScaleSettingObserver = new FontScaleSettingObserver();
11274
11275        //mUsageStatsService.monitorPackages();
11276    }
11277
11278    private void startPersistentApps(int matchFlags) {
11279        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11280
11281        synchronized (this) {
11282            try {
11283                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11284                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11285                for (ApplicationInfo app : apps) {
11286                    if (!"android".equals(app.packageName)) {
11287                        addAppLocked(app, false, null /* ABI override */);
11288                    }
11289                }
11290            } catch (RemoteException ex) {
11291            }
11292        }
11293    }
11294
11295    /**
11296     * When a user is unlocked, we need to install encryption-unaware providers
11297     * belonging to any running apps.
11298     */
11299    private void installEncryptionUnawareProviders(int userId) {
11300        // We're only interested in providers that are encryption unaware, and
11301        // we don't care about uninstalled apps, since there's no way they're
11302        // running at this point.
11303        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11304
11305        synchronized (this) {
11306            final int NP = mProcessNames.getMap().size();
11307            for (int ip = 0; ip < NP; ip++) {
11308                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11309                final int NA = apps.size();
11310                for (int ia = 0; ia < NA; ia++) {
11311                    final ProcessRecord app = apps.valueAt(ia);
11312                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11313
11314                    final int NG = app.pkgList.size();
11315                    for (int ig = 0; ig < NG; ig++) {
11316                        try {
11317                            final String pkgName = app.pkgList.keyAt(ig);
11318                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11319                                    .getPackageInfo(pkgName, matchFlags, userId);
11320                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11321                                for (ProviderInfo pi : pkgInfo.providers) {
11322                                    // TODO: keep in sync with generateApplicationProvidersLocked
11323                                    final boolean processMatch = Objects.equals(pi.processName,
11324                                            app.processName) || pi.multiprocess;
11325                                    final boolean userMatch = isSingleton(pi.processName,
11326                                            pi.applicationInfo, pi.name, pi.flags)
11327                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11328                                    if (processMatch && userMatch) {
11329                                        Log.v(TAG, "Installing " + pi);
11330                                        app.thread.scheduleInstallProvider(pi);
11331                                    } else {
11332                                        Log.v(TAG, "Skipping " + pi);
11333                                    }
11334                                }
11335                            }
11336                        } catch (RemoteException ignored) {
11337                        }
11338                    }
11339                }
11340            }
11341        }
11342    }
11343
11344    /**
11345     * Allows apps to retrieve the MIME type of a URI.
11346     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11347     * users, then it does not need permission to access the ContentProvider.
11348     * Either, it needs cross-user uri grants.
11349     *
11350     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11351     *
11352     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11353     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11354     */
11355    public String getProviderMimeType(Uri uri, int userId) {
11356        enforceNotIsolatedCaller("getProviderMimeType");
11357        final String name = uri.getAuthority();
11358        int callingUid = Binder.getCallingUid();
11359        int callingPid = Binder.getCallingPid();
11360        long ident = 0;
11361        boolean clearedIdentity = false;
11362        synchronized (this) {
11363            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11364        }
11365        if (canClearIdentity(callingPid, callingUid, userId)) {
11366            clearedIdentity = true;
11367            ident = Binder.clearCallingIdentity();
11368        }
11369        ContentProviderHolder holder = null;
11370        try {
11371            holder = getContentProviderExternalUnchecked(name, null, userId);
11372            if (holder != null) {
11373                return holder.provider.getType(uri);
11374            }
11375        } catch (RemoteException e) {
11376            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11377            return null;
11378        } catch (Exception e) {
11379            Log.w(TAG, "Exception while determining type of " + uri, e);
11380            return null;
11381        } finally {
11382            // We need to clear the identity to call removeContentProviderExternalUnchecked
11383            if (!clearedIdentity) {
11384                ident = Binder.clearCallingIdentity();
11385            }
11386            try {
11387                if (holder != null) {
11388                    removeContentProviderExternalUnchecked(name, null, userId);
11389                }
11390            } finally {
11391                Binder.restoreCallingIdentity(ident);
11392            }
11393        }
11394
11395        return null;
11396    }
11397
11398    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11399        if (UserHandle.getUserId(callingUid) == userId) {
11400            return true;
11401        }
11402        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11403                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11404                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11405                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11406                return true;
11407        }
11408        return false;
11409    }
11410
11411    // =========================================================
11412    // GLOBAL MANAGEMENT
11413    // =========================================================
11414
11415    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11416            boolean isolated, int isolatedUid) {
11417        String proc = customProcess != null ? customProcess : info.processName;
11418        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11419        final int userId = UserHandle.getUserId(info.uid);
11420        int uid = info.uid;
11421        if (isolated) {
11422            if (isolatedUid == 0) {
11423                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11424                while (true) {
11425                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11426                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11427                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11428                    }
11429                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11430                    mNextIsolatedProcessUid++;
11431                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11432                        // No process for this uid, use it.
11433                        break;
11434                    }
11435                    stepsLeft--;
11436                    if (stepsLeft <= 0) {
11437                        return null;
11438                    }
11439                }
11440            } else {
11441                // Special case for startIsolatedProcess (internal only), where
11442                // the uid of the isolated process is specified by the caller.
11443                uid = isolatedUid;
11444            }
11445        }
11446        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11447        if (!mBooted && !mBooting
11448                && userId == UserHandle.USER_SYSTEM
11449                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11450            r.persistent = true;
11451        }
11452        addProcessNameLocked(r);
11453        return r;
11454    }
11455
11456    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11457            String abiOverride) {
11458        ProcessRecord app;
11459        if (!isolated) {
11460            app = getProcessRecordLocked(info.processName, info.uid, true);
11461        } else {
11462            app = null;
11463        }
11464
11465        if (app == null) {
11466            app = newProcessRecordLocked(info, null, isolated, 0);
11467            updateLruProcessLocked(app, false, null);
11468            updateOomAdjLocked();
11469        }
11470
11471        // This package really, really can not be stopped.
11472        try {
11473            AppGlobals.getPackageManager().setPackageStoppedState(
11474                    info.packageName, false, UserHandle.getUserId(app.uid));
11475        } catch (RemoteException e) {
11476        } catch (IllegalArgumentException e) {
11477            Slog.w(TAG, "Failed trying to unstop package "
11478                    + info.packageName + ": " + e);
11479        }
11480
11481        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11482            app.persistent = true;
11483            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11484        }
11485        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11486            mPersistentStartingProcesses.add(app);
11487            startProcessLocked(app, "added application", app.processName, abiOverride,
11488                    null /* entryPoint */, null /* entryPointArgs */);
11489        }
11490
11491        return app;
11492    }
11493
11494    public void unhandledBack() {
11495        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11496                "unhandledBack()");
11497
11498        synchronized(this) {
11499            final long origId = Binder.clearCallingIdentity();
11500            try {
11501                getFocusedStack().unhandledBackLocked();
11502            } finally {
11503                Binder.restoreCallingIdentity(origId);
11504            }
11505        }
11506    }
11507
11508    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11509        enforceNotIsolatedCaller("openContentUri");
11510        final int userId = UserHandle.getCallingUserId();
11511        String name = uri.getAuthority();
11512        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11513        ParcelFileDescriptor pfd = null;
11514        if (cph != null) {
11515            // We record the binder invoker's uid in thread-local storage before
11516            // going to the content provider to open the file.  Later, in the code
11517            // that handles all permissions checks, we look for this uid and use
11518            // that rather than the Activity Manager's own uid.  The effect is that
11519            // we do the check against the caller's permissions even though it looks
11520            // to the content provider like the Activity Manager itself is making
11521            // the request.
11522            Binder token = new Binder();
11523            sCallerIdentity.set(new Identity(
11524                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11525            try {
11526                pfd = cph.provider.openFile(null, uri, "r", null, token);
11527            } catch (FileNotFoundException e) {
11528                // do nothing; pfd will be returned null
11529            } finally {
11530                // Ensure that whatever happens, we clean up the identity state
11531                sCallerIdentity.remove();
11532                // Ensure we're done with the provider.
11533                removeContentProviderExternalUnchecked(name, null, userId);
11534            }
11535        } else {
11536            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11537        }
11538        return pfd;
11539    }
11540
11541    // Actually is sleeping or shutting down or whatever else in the future
11542    // is an inactive state.
11543    boolean isSleepingOrShuttingDownLocked() {
11544        return isSleepingLocked() || mShuttingDown;
11545    }
11546
11547    boolean isShuttingDownLocked() {
11548        return mShuttingDown;
11549    }
11550
11551    boolean isSleepingLocked() {
11552        return mSleeping;
11553    }
11554
11555    void onWakefulnessChanged(int wakefulness) {
11556        synchronized(this) {
11557            mWakefulness = wakefulness;
11558            updateSleepIfNeededLocked();
11559        }
11560    }
11561
11562    void finishRunningVoiceLocked() {
11563        if (mRunningVoice != null) {
11564            mRunningVoice = null;
11565            mVoiceWakeLock.release();
11566            updateSleepIfNeededLocked();
11567        }
11568    }
11569
11570    void startTimeTrackingFocusedActivityLocked() {
11571        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11572            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11573        }
11574    }
11575
11576    void updateSleepIfNeededLocked() {
11577        if (mSleeping && !shouldSleepLocked()) {
11578            mSleeping = false;
11579            startTimeTrackingFocusedActivityLocked();
11580            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11581            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11582            updateOomAdjLocked();
11583        } else if (!mSleeping && shouldSleepLocked()) {
11584            mSleeping = true;
11585            if (mCurAppTimeTracker != null) {
11586                mCurAppTimeTracker.stop();
11587            }
11588            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11589            mStackSupervisor.goingToSleepLocked();
11590            updateOomAdjLocked();
11591
11592            // Initialize the wake times of all processes.
11593            checkExcessivePowerUsageLocked(false);
11594            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11595            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11596            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11597        }
11598    }
11599
11600    private boolean shouldSleepLocked() {
11601        // Resume applications while running a voice interactor.
11602        if (mRunningVoice != null) {
11603            return false;
11604        }
11605
11606        // TODO: Transform the lock screen state into a sleep token instead.
11607        switch (mWakefulness) {
11608            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11609            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11610            case PowerManagerInternal.WAKEFULNESS_DOZING:
11611                // Pause applications whenever the lock screen is shown or any sleep
11612                // tokens have been acquired.
11613                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11614            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11615            default:
11616                // If we're asleep then pause applications unconditionally.
11617                return true;
11618        }
11619    }
11620
11621    /** Pokes the task persister. */
11622    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11623        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11624    }
11625
11626    /** Notifies all listeners when the task stack has changed. */
11627    void notifyTaskStackChangedLocked() {
11628        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11629        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11630        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11631        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11632    }
11633
11634    /** Notifies all listeners when an Activity is pinned. */
11635    void notifyActivityPinnedLocked() {
11636        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11637        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11638    }
11639
11640    /**
11641     * Notifies all listeners when an attempt was made to start an an activity that is already
11642     * running in the pinned stack and the activity was not actually started, but the task is
11643     * either brought to the front or a new Intent is delivered to it.
11644     */
11645    void notifyPinnedActivityRestartAttemptLocked() {
11646        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11647        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11648    }
11649
11650    /** Notifies all listeners when the pinned stack animation ends. */
11651    @Override
11652    public void notifyPinnedStackAnimationEnded() {
11653        synchronized (this) {
11654            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11655            mHandler.obtainMessage(
11656                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11657        }
11658    }
11659
11660    @Override
11661    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11662        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11663    }
11664
11665    @Override
11666    public boolean shutdown(int timeout) {
11667        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11668                != PackageManager.PERMISSION_GRANTED) {
11669            throw new SecurityException("Requires permission "
11670                    + android.Manifest.permission.SHUTDOWN);
11671        }
11672
11673        boolean timedout = false;
11674
11675        synchronized(this) {
11676            mShuttingDown = true;
11677            updateEventDispatchingLocked();
11678            timedout = mStackSupervisor.shutdownLocked(timeout);
11679        }
11680
11681        mAppOpsService.shutdown();
11682        if (mUsageStatsService != null) {
11683            mUsageStatsService.prepareShutdown();
11684        }
11685        mBatteryStatsService.shutdown();
11686        synchronized (this) {
11687            mProcessStats.shutdownLocked();
11688            notifyTaskPersisterLocked(null, true);
11689        }
11690
11691        return timedout;
11692    }
11693
11694    public final void activitySlept(IBinder token) {
11695        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11696
11697        final long origId = Binder.clearCallingIdentity();
11698
11699        synchronized (this) {
11700            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11701            if (r != null) {
11702                mStackSupervisor.activitySleptLocked(r);
11703            }
11704        }
11705
11706        Binder.restoreCallingIdentity(origId);
11707    }
11708
11709    private String lockScreenShownToString() {
11710        switch (mLockScreenShown) {
11711            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11712            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11713            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11714            default: return "Unknown=" + mLockScreenShown;
11715        }
11716    }
11717
11718    void logLockScreen(String msg) {
11719        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11720                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11721                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11722                + " mSleeping=" + mSleeping);
11723    }
11724
11725    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11726        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11727        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11728        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11729            boolean wasRunningVoice = mRunningVoice != null;
11730            mRunningVoice = session;
11731            if (!wasRunningVoice) {
11732                mVoiceWakeLock.acquire();
11733                updateSleepIfNeededLocked();
11734            }
11735        }
11736    }
11737
11738    private void updateEventDispatchingLocked() {
11739        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11740    }
11741
11742    public void setLockScreenShown(boolean showing, boolean occluded) {
11743        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11744                != PackageManager.PERMISSION_GRANTED) {
11745            throw new SecurityException("Requires permission "
11746                    + android.Manifest.permission.DEVICE_POWER);
11747        }
11748
11749        synchronized(this) {
11750            long ident = Binder.clearCallingIdentity();
11751            try {
11752                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11753                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11754                if (showing && occluded) {
11755                    // The lock screen is currently showing, but is occluded by a window that can
11756                    // show on top of the lock screen. In this can we want to dismiss the docked
11757                    // stack since it will be complicated/risky to try to put the activity on top
11758                    // of the lock screen in the right fullscreen configuration.
11759                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11760                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11761                }
11762
11763                updateSleepIfNeededLocked();
11764            } finally {
11765                Binder.restoreCallingIdentity(ident);
11766            }
11767        }
11768    }
11769
11770    @Override
11771    public void notifyLockedProfile(@UserIdInt int userId) {
11772        try {
11773            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11774                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11775            }
11776        } catch (RemoteException ex) {
11777            throw new SecurityException("Fail to check is caller a privileged app", ex);
11778        }
11779
11780        synchronized (this) {
11781            if (mStackSupervisor.isUserLockedProfile(userId)) {
11782                final long ident = Binder.clearCallingIdentity();
11783                try {
11784                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11785                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11786                        // If there is no device lock, we will show the profile's credential page.
11787                        mActivityStarter.showConfirmDeviceCredential(userId);
11788                    } else {
11789                        // Showing launcher to avoid user entering credential twice.
11790                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11791                    }
11792                } finally {
11793                    Binder.restoreCallingIdentity(ident);
11794                }
11795            }
11796        }
11797    }
11798
11799    @Override
11800    public void startConfirmDeviceCredentialIntent(Intent intent) {
11801        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11802        synchronized (this) {
11803            final long ident = Binder.clearCallingIdentity();
11804            try {
11805                mActivityStarter.startConfirmCredentialIntent(intent);
11806            } finally {
11807                Binder.restoreCallingIdentity(ident);
11808            }
11809        }
11810    }
11811
11812    @Override
11813    public void stopAppSwitches() {
11814        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11815                != PackageManager.PERMISSION_GRANTED) {
11816            throw new SecurityException("viewquires permission "
11817                    + android.Manifest.permission.STOP_APP_SWITCHES);
11818        }
11819
11820        synchronized(this) {
11821            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11822                    + APP_SWITCH_DELAY_TIME;
11823            mDidAppSwitch = false;
11824            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11825            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11826            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11827        }
11828    }
11829
11830    public void resumeAppSwitches() {
11831        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11832                != PackageManager.PERMISSION_GRANTED) {
11833            throw new SecurityException("Requires permission "
11834                    + android.Manifest.permission.STOP_APP_SWITCHES);
11835        }
11836
11837        synchronized(this) {
11838            // Note that we don't execute any pending app switches... we will
11839            // let those wait until either the timeout, or the next start
11840            // activity request.
11841            mAppSwitchesAllowedTime = 0;
11842        }
11843    }
11844
11845    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11846            int callingPid, int callingUid, String name) {
11847        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11848            return true;
11849        }
11850
11851        int perm = checkComponentPermission(
11852                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11853                sourceUid, -1, true);
11854        if (perm == PackageManager.PERMISSION_GRANTED) {
11855            return true;
11856        }
11857
11858        // If the actual IPC caller is different from the logical source, then
11859        // also see if they are allowed to control app switches.
11860        if (callingUid != -1 && callingUid != sourceUid) {
11861            perm = checkComponentPermission(
11862                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11863                    callingUid, -1, true);
11864            if (perm == PackageManager.PERMISSION_GRANTED) {
11865                return true;
11866            }
11867        }
11868
11869        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11870        return false;
11871    }
11872
11873    public void setDebugApp(String packageName, boolean waitForDebugger,
11874            boolean persistent) {
11875        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11876                "setDebugApp()");
11877
11878        long ident = Binder.clearCallingIdentity();
11879        try {
11880            // Note that this is not really thread safe if there are multiple
11881            // callers into it at the same time, but that's not a situation we
11882            // care about.
11883            if (persistent) {
11884                final ContentResolver resolver = mContext.getContentResolver();
11885                Settings.Global.putString(
11886                    resolver, Settings.Global.DEBUG_APP,
11887                    packageName);
11888                Settings.Global.putInt(
11889                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11890                    waitForDebugger ? 1 : 0);
11891            }
11892
11893            synchronized (this) {
11894                if (!persistent) {
11895                    mOrigDebugApp = mDebugApp;
11896                    mOrigWaitForDebugger = mWaitForDebugger;
11897                }
11898                mDebugApp = packageName;
11899                mWaitForDebugger = waitForDebugger;
11900                mDebugTransient = !persistent;
11901                if (packageName != null) {
11902                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11903                            false, UserHandle.USER_ALL, "set debug app");
11904                }
11905            }
11906        } finally {
11907            Binder.restoreCallingIdentity(ident);
11908        }
11909    }
11910
11911    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11912        synchronized (this) {
11913            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11914            if (!isDebuggable) {
11915                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11916                    throw new SecurityException("Process not debuggable: " + app.packageName);
11917                }
11918            }
11919
11920            mTrackAllocationApp = processName;
11921        }
11922    }
11923
11924    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11925        synchronized (this) {
11926            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11927            if (!isDebuggable) {
11928                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11929                    throw new SecurityException("Process not debuggable: " + app.packageName);
11930                }
11931            }
11932            mProfileApp = processName;
11933            mProfileFile = profilerInfo.profileFile;
11934            if (mProfileFd != null) {
11935                try {
11936                    mProfileFd.close();
11937                } catch (IOException e) {
11938                }
11939                mProfileFd = null;
11940            }
11941            mProfileFd = profilerInfo.profileFd;
11942            mSamplingInterval = profilerInfo.samplingInterval;
11943            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11944            mProfileType = 0;
11945        }
11946    }
11947
11948    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11949        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11950        if (!isDebuggable) {
11951            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11952                throw new SecurityException("Process not debuggable: " + app.packageName);
11953            }
11954        }
11955        mNativeDebuggingApp = processName;
11956    }
11957
11958    @Override
11959    public void setAlwaysFinish(boolean enabled) {
11960        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11961                "setAlwaysFinish()");
11962
11963        long ident = Binder.clearCallingIdentity();
11964        try {
11965            Settings.Global.putInt(
11966                    mContext.getContentResolver(),
11967                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11968
11969            synchronized (this) {
11970                mAlwaysFinishActivities = enabled;
11971            }
11972        } finally {
11973            Binder.restoreCallingIdentity(ident);
11974        }
11975    }
11976
11977    @Override
11978    public void setLenientBackgroundCheck(boolean enabled) {
11979        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11980                "setLenientBackgroundCheck()");
11981
11982        long ident = Binder.clearCallingIdentity();
11983        try {
11984            Settings.Global.putInt(
11985                    mContext.getContentResolver(),
11986                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11987
11988            synchronized (this) {
11989                mLenientBackgroundCheck = enabled;
11990            }
11991        } finally {
11992            Binder.restoreCallingIdentity(ident);
11993        }
11994    }
11995
11996    @Override
11997    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11998        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11999                "setActivityController()");
12000        synchronized (this) {
12001            mController = controller;
12002            mControllerIsAMonkey = imAMonkey;
12003            Watchdog.getInstance().setActivityController(controller);
12004        }
12005    }
12006
12007    @Override
12008    public void setUserIsMonkey(boolean userIsMonkey) {
12009        synchronized (this) {
12010            synchronized (mPidsSelfLocked) {
12011                final int callingPid = Binder.getCallingPid();
12012                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12013                if (precessRecord == null) {
12014                    throw new SecurityException("Unknown process: " + callingPid);
12015                }
12016                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12017                    throw new SecurityException("Only an instrumentation process "
12018                            + "with a UiAutomation can call setUserIsMonkey");
12019                }
12020            }
12021            mUserIsMonkey = userIsMonkey;
12022        }
12023    }
12024
12025    @Override
12026    public boolean isUserAMonkey() {
12027        synchronized (this) {
12028            // If there is a controller also implies the user is a monkey.
12029            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12030        }
12031    }
12032
12033    public void requestBugReport(int bugreportType) {
12034        String service = null;
12035        switch (bugreportType) {
12036            case ActivityManager.BUGREPORT_OPTION_FULL:
12037                service = "bugreport";
12038                break;
12039            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12040                service = "bugreportplus";
12041                break;
12042            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12043                service = "bugreportremote";
12044                break;
12045        }
12046        if (service == null) {
12047            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12048                    + bugreportType);
12049        }
12050        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12051        SystemProperties.set("ctl.start", service);
12052    }
12053
12054    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12055        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12056    }
12057
12058    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12059        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12060            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12061        }
12062        return KEY_DISPATCHING_TIMEOUT;
12063    }
12064
12065    @Override
12066    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12067        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12068                != PackageManager.PERMISSION_GRANTED) {
12069            throw new SecurityException("Requires permission "
12070                    + android.Manifest.permission.FILTER_EVENTS);
12071        }
12072        ProcessRecord proc;
12073        long timeout;
12074        synchronized (this) {
12075            synchronized (mPidsSelfLocked) {
12076                proc = mPidsSelfLocked.get(pid);
12077            }
12078            timeout = getInputDispatchingTimeoutLocked(proc);
12079        }
12080
12081        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12082            return -1;
12083        }
12084
12085        return timeout;
12086    }
12087
12088    /**
12089     * Handle input dispatching timeouts.
12090     * Returns whether input dispatching should be aborted or not.
12091     */
12092    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12093            final ActivityRecord activity, final ActivityRecord parent,
12094            final boolean aboveSystem, String reason) {
12095        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12096                != PackageManager.PERMISSION_GRANTED) {
12097            throw new SecurityException("Requires permission "
12098                    + android.Manifest.permission.FILTER_EVENTS);
12099        }
12100
12101        final String annotation;
12102        if (reason == null) {
12103            annotation = "Input dispatching timed out";
12104        } else {
12105            annotation = "Input dispatching timed out (" + reason + ")";
12106        }
12107
12108        if (proc != null) {
12109            synchronized (this) {
12110                if (proc.debugging) {
12111                    return false;
12112                }
12113
12114                if (mDidDexOpt) {
12115                    // Give more time since we were dexopting.
12116                    mDidDexOpt = false;
12117                    return false;
12118                }
12119
12120                if (proc.instrumentationClass != null) {
12121                    Bundle info = new Bundle();
12122                    info.putString("shortMsg", "keyDispatchingTimedOut");
12123                    info.putString("longMsg", annotation);
12124                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12125                    return true;
12126                }
12127            }
12128            mHandler.post(new Runnable() {
12129                @Override
12130                public void run() {
12131                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12132                }
12133            });
12134        }
12135
12136        return true;
12137    }
12138
12139    @Override
12140    public Bundle getAssistContextExtras(int requestType) {
12141        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12142                null, null, true /* focused */, true /* newSessionId */,
12143                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12144        if (pae == null) {
12145            return null;
12146        }
12147        synchronized (pae) {
12148            while (!pae.haveResult) {
12149                try {
12150                    pae.wait();
12151                } catch (InterruptedException e) {
12152                }
12153            }
12154        }
12155        synchronized (this) {
12156            buildAssistBundleLocked(pae, pae.result);
12157            mPendingAssistExtras.remove(pae);
12158            mUiHandler.removeCallbacks(pae);
12159        }
12160        return pae.extras;
12161    }
12162
12163    @Override
12164    public boolean isAssistDataAllowedOnCurrentActivity() {
12165        int userId;
12166        synchronized (this) {
12167            userId = mUserController.getCurrentUserIdLocked();
12168            ActivityRecord activity = getFocusedStack().topActivity();
12169            if (activity == null) {
12170                return false;
12171            }
12172            userId = activity.userId;
12173        }
12174        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12175                Context.DEVICE_POLICY_SERVICE);
12176        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12177    }
12178
12179    @Override
12180    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12181        long ident = Binder.clearCallingIdentity();
12182        try {
12183            synchronized (this) {
12184                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12185                ActivityRecord top = getFocusedStack().topActivity();
12186                if (top != caller) {
12187                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12188                            + " is not current top " + top);
12189                    return false;
12190                }
12191                if (!top.nowVisible) {
12192                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12193                            + " is not visible");
12194                    return false;
12195                }
12196            }
12197            AssistUtils utils = new AssistUtils(mContext);
12198            return utils.showSessionForActiveService(args,
12199                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12200        } finally {
12201            Binder.restoreCallingIdentity(ident);
12202        }
12203    }
12204
12205    @Override
12206    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12207            Bundle receiverExtras,
12208            IBinder activityToken, boolean focused, boolean newSessionId) {
12209        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12210                activityToken, focused, newSessionId,
12211                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12212                != null;
12213    }
12214
12215    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12216            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12217            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12218        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12219                "enqueueAssistContext()");
12220        synchronized (this) {
12221            ActivityRecord activity = getFocusedStack().topActivity();
12222            if (activity == null) {
12223                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12224                return null;
12225            }
12226            if (activity.app == null || activity.app.thread == null) {
12227                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12228                return null;
12229            }
12230            if (focused) {
12231                if (activityToken != null) {
12232                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12233                    if (activity != caller) {
12234                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12235                                + " is not current top " + activity);
12236                        return null;
12237                    }
12238                }
12239            } else {
12240                activity = ActivityRecord.forTokenLocked(activityToken);
12241                if (activity == null) {
12242                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12243                            + " couldn't be found");
12244                    return null;
12245                }
12246            }
12247
12248            PendingAssistExtras pae;
12249            Bundle extras = new Bundle();
12250            if (args != null) {
12251                extras.putAll(args);
12252            }
12253            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12254            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12255            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12256                    userHandle);
12257            // Increment the sessionId if necessary
12258            if (newSessionId) {
12259                mViSessionId++;
12260            }
12261            try {
12262                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12263                        requestType, mViSessionId);
12264                mPendingAssistExtras.add(pae);
12265                mUiHandler.postDelayed(pae, timeout);
12266            } catch (RemoteException e) {
12267                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12268                return null;
12269            }
12270            return pae;
12271        }
12272    }
12273
12274    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12275        IResultReceiver receiver;
12276        synchronized (this) {
12277            mPendingAssistExtras.remove(pae);
12278            receiver = pae.receiver;
12279        }
12280        if (receiver != null) {
12281            // Caller wants result sent back to them.
12282            Bundle sendBundle = new Bundle();
12283            // At least return the receiver extras
12284            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12285                    pae.receiverExtras);
12286            try {
12287                pae.receiver.send(0, sendBundle);
12288            } catch (RemoteException e) {
12289            }
12290        }
12291    }
12292
12293    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12294        if (result != null) {
12295            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12296        }
12297        if (pae.hint != null) {
12298            pae.extras.putBoolean(pae.hint, true);
12299        }
12300    }
12301
12302    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12303            AssistContent content, Uri referrer) {
12304        PendingAssistExtras pae = (PendingAssistExtras)token;
12305        synchronized (pae) {
12306            pae.result = extras;
12307            pae.structure = structure;
12308            pae.content = content;
12309            if (referrer != null) {
12310                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12311            }
12312            pae.haveResult = true;
12313            pae.notifyAll();
12314            if (pae.intent == null && pae.receiver == null) {
12315                // Caller is just waiting for the result.
12316                return;
12317            }
12318        }
12319
12320        // We are now ready to launch the assist activity.
12321        IResultReceiver sendReceiver = null;
12322        Bundle sendBundle = null;
12323        synchronized (this) {
12324            buildAssistBundleLocked(pae, extras);
12325            boolean exists = mPendingAssistExtras.remove(pae);
12326            mUiHandler.removeCallbacks(pae);
12327            if (!exists) {
12328                // Timed out.
12329                return;
12330            }
12331            if ((sendReceiver=pae.receiver) != null) {
12332                // Caller wants result sent back to them.
12333                sendBundle = new Bundle();
12334                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12335                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12336                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12337                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12338                        pae.receiverExtras);
12339            }
12340        }
12341        if (sendReceiver != null) {
12342            try {
12343                sendReceiver.send(0, sendBundle);
12344            } catch (RemoteException e) {
12345            }
12346            return;
12347        }
12348
12349        long ident = Binder.clearCallingIdentity();
12350        try {
12351            pae.intent.replaceExtras(pae.extras);
12352            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12353                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12354                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12355            closeSystemDialogs("assist");
12356            try {
12357                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12358            } catch (ActivityNotFoundException e) {
12359                Slog.w(TAG, "No activity to handle assist action.", e);
12360            }
12361        } finally {
12362            Binder.restoreCallingIdentity(ident);
12363        }
12364    }
12365
12366    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12367            Bundle args) {
12368        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12369                true /* focused */, true /* newSessionId */,
12370                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12371    }
12372
12373    public void registerProcessObserver(IProcessObserver observer) {
12374        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12375                "registerProcessObserver()");
12376        synchronized (this) {
12377            mProcessObservers.register(observer);
12378        }
12379    }
12380
12381    @Override
12382    public void unregisterProcessObserver(IProcessObserver observer) {
12383        synchronized (this) {
12384            mProcessObservers.unregister(observer);
12385        }
12386    }
12387
12388    @Override
12389    public void registerUidObserver(IUidObserver observer, int which) {
12390        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12391                "registerUidObserver()");
12392        synchronized (this) {
12393            mUidObservers.register(observer, which);
12394        }
12395    }
12396
12397    @Override
12398    public void unregisterUidObserver(IUidObserver observer) {
12399        synchronized (this) {
12400            mUidObservers.unregister(observer);
12401        }
12402    }
12403
12404    @Override
12405    public boolean convertFromTranslucent(IBinder token) {
12406        final long origId = Binder.clearCallingIdentity();
12407        try {
12408            synchronized (this) {
12409                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12410                if (r == null) {
12411                    return false;
12412                }
12413                final boolean translucentChanged = r.changeWindowTranslucency(true);
12414                if (translucentChanged) {
12415                    r.task.stack.releaseBackgroundResources(r);
12416                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12417                }
12418                mWindowManager.setAppFullscreen(token, true);
12419                return translucentChanged;
12420            }
12421        } finally {
12422            Binder.restoreCallingIdentity(origId);
12423        }
12424    }
12425
12426    @Override
12427    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12428        final long origId = Binder.clearCallingIdentity();
12429        try {
12430            synchronized (this) {
12431                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12432                if (r == null) {
12433                    return false;
12434                }
12435                int index = r.task.mActivities.lastIndexOf(r);
12436                if (index > 0) {
12437                    ActivityRecord under = r.task.mActivities.get(index - 1);
12438                    under.returningOptions = options;
12439                }
12440                final boolean translucentChanged = r.changeWindowTranslucency(false);
12441                if (translucentChanged) {
12442                    r.task.stack.convertActivityToTranslucent(r);
12443                }
12444                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12445                mWindowManager.setAppFullscreen(token, false);
12446                return translucentChanged;
12447            }
12448        } finally {
12449            Binder.restoreCallingIdentity(origId);
12450        }
12451    }
12452
12453    @Override
12454    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12455        final long origId = Binder.clearCallingIdentity();
12456        try {
12457            synchronized (this) {
12458                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12459                if (r != null) {
12460                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12461                }
12462            }
12463            return false;
12464        } finally {
12465            Binder.restoreCallingIdentity(origId);
12466        }
12467    }
12468
12469    @Override
12470    public boolean isBackgroundVisibleBehind(IBinder token) {
12471        final long origId = Binder.clearCallingIdentity();
12472        try {
12473            synchronized (this) {
12474                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12475                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12476                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12477                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12478                return visible;
12479            }
12480        } finally {
12481            Binder.restoreCallingIdentity(origId);
12482        }
12483    }
12484
12485    @Override
12486    public ActivityOptions getActivityOptions(IBinder token) {
12487        final long origId = Binder.clearCallingIdentity();
12488        try {
12489            synchronized (this) {
12490                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12491                if (r != null) {
12492                    final ActivityOptions activityOptions = r.pendingOptions;
12493                    r.pendingOptions = null;
12494                    return activityOptions;
12495                }
12496                return null;
12497            }
12498        } finally {
12499            Binder.restoreCallingIdentity(origId);
12500        }
12501    }
12502
12503    @Override
12504    public void setImmersive(IBinder token, boolean immersive) {
12505        synchronized(this) {
12506            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12507            if (r == null) {
12508                throw new IllegalArgumentException();
12509            }
12510            r.immersive = immersive;
12511
12512            // update associated state if we're frontmost
12513            if (r == mFocusedActivity) {
12514                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12515                applyUpdateLockStateLocked(r);
12516            }
12517        }
12518    }
12519
12520    @Override
12521    public boolean isImmersive(IBinder token) {
12522        synchronized (this) {
12523            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12524            if (r == null) {
12525                throw new IllegalArgumentException();
12526            }
12527            return r.immersive;
12528        }
12529    }
12530
12531    public void setVrThread(int tid) {
12532        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12533            throw new UnsupportedOperationException("VR mode not supported on this device!");
12534        }
12535
12536        synchronized (this) {
12537            ProcessRecord proc;
12538            synchronized (mPidsSelfLocked) {
12539                final int pid = Binder.getCallingPid();
12540                proc = mPidsSelfLocked.get(pid);
12541                if (proc != null && mInVrMode && tid >= 0) {
12542                    // ensure the tid belongs to the process
12543                    if (!Process.isThreadInProcess(pid, tid)) {
12544                        throw new IllegalArgumentException("VR thread does not belong to process");
12545                    }
12546                    // reset existing VR thread to CFS
12547                    if (proc.vrThreadTid != 0) {
12548                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12549                    }
12550                    // add check to guarantee that tid belongs to pid?
12551                    proc.vrThreadTid = tid;
12552                    // promote to FIFO now if the tid is non-zero
12553                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12554                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12555                    }
12556                } else {
12557                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12558                }
12559            }
12560        }
12561    }
12562
12563    @Override
12564    public void setRenderThread(int tid) {
12565        synchronized (this) {
12566            ProcessRecord proc;
12567            synchronized (mPidsSelfLocked) {
12568                int pid = Binder.getCallingPid();
12569                proc = mPidsSelfLocked.get(pid);
12570                if (mUseFifoUiScheduling && proc != null && proc.renderThreadTid == 0 && tid > 0) {
12571                    // ensure the tid belongs to the process
12572                    if (!Process.isThreadInProcess(pid, tid)) {
12573                        throw new IllegalArgumentException(
12574                            "Render thread does not belong to process");
12575                    }
12576                    proc.renderThreadTid = tid;
12577                    if (DEBUG_OOM_ADJ) {
12578                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12579                    }
12580                    // promote to FIFO now
12581                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12582                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12583                        Process.setThreadScheduler(proc.renderThreadTid,
12584                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12585                    }
12586                } else {
12587                    if (DEBUG_OOM_ADJ) {
12588                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12589                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12590                               mUseFifoUiScheduling);
12591                    }
12592                }
12593            }
12594        }
12595    }
12596
12597    @Override
12598    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12599        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12600            throw new UnsupportedOperationException("VR mode not supported on this device!");
12601        }
12602
12603        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12604
12605        ActivityRecord r;
12606        synchronized (this) {
12607            r = ActivityRecord.isInStackLocked(token);
12608        }
12609
12610        if (r == null) {
12611            throw new IllegalArgumentException();
12612        }
12613
12614        int err;
12615        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12616                VrManagerInternal.NO_ERROR) {
12617            return err;
12618        }
12619
12620        synchronized(this) {
12621            r.requestedVrComponent = (enabled) ? packageName : null;
12622
12623            // Update associated state if this activity is currently focused
12624            if (r == mFocusedActivity) {
12625                applyUpdateVrModeLocked(r);
12626            }
12627            return 0;
12628        }
12629    }
12630
12631    @Override
12632    public boolean isVrModePackageEnabled(ComponentName packageName) {
12633        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12634            throw new UnsupportedOperationException("VR mode not supported on this device!");
12635        }
12636
12637        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12638
12639        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12640                VrManagerInternal.NO_ERROR;
12641    }
12642
12643    public boolean isTopActivityImmersive() {
12644        enforceNotIsolatedCaller("startActivity");
12645        synchronized (this) {
12646            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12647            return (r != null) ? r.immersive : false;
12648        }
12649    }
12650
12651    @Override
12652    public boolean isTopOfTask(IBinder token) {
12653        synchronized (this) {
12654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12655            if (r == null) {
12656                throw new IllegalArgumentException();
12657            }
12658            return r.task.getTopActivity() == r;
12659        }
12660    }
12661
12662    public final void enterSafeMode() {
12663        synchronized(this) {
12664            // It only makes sense to do this before the system is ready
12665            // and started launching other packages.
12666            if (!mSystemReady) {
12667                try {
12668                    AppGlobals.getPackageManager().enterSafeMode();
12669                } catch (RemoteException e) {
12670                }
12671            }
12672
12673            mSafeMode = true;
12674        }
12675    }
12676
12677    public final void showSafeModeOverlay() {
12678        View v = LayoutInflater.from(mContext).inflate(
12679                com.android.internal.R.layout.safe_mode, null);
12680        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12681        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12682        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12683        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12684        lp.gravity = Gravity.BOTTOM | Gravity.START;
12685        lp.format = v.getBackground().getOpacity();
12686        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12687                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12688        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12689        ((WindowManager)mContext.getSystemService(
12690                Context.WINDOW_SERVICE)).addView(v, lp);
12691    }
12692
12693    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12694        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12695            return;
12696        }
12697        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12698        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12699        synchronized (stats) {
12700            if (mBatteryStatsService.isOnBattery()) {
12701                mBatteryStatsService.enforceCallingPermission();
12702                int MY_UID = Binder.getCallingUid();
12703                final int uid;
12704                if (sender == null) {
12705                    uid = sourceUid;
12706                } else {
12707                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12708                }
12709                BatteryStatsImpl.Uid.Pkg pkg =
12710                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12711                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12712                pkg.noteWakeupAlarmLocked(tag);
12713            }
12714        }
12715    }
12716
12717    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12718        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12719            return;
12720        }
12721        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12722        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12723        synchronized (stats) {
12724            mBatteryStatsService.enforceCallingPermission();
12725            int MY_UID = Binder.getCallingUid();
12726            final int uid;
12727            if (sender == null) {
12728                uid = sourceUid;
12729            } else {
12730                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12731            }
12732            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12733        }
12734    }
12735
12736    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12737        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12738            return;
12739        }
12740        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12741        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12742        synchronized (stats) {
12743            mBatteryStatsService.enforceCallingPermission();
12744            int MY_UID = Binder.getCallingUid();
12745            final int uid;
12746            if (sender == null) {
12747                uid = sourceUid;
12748            } else {
12749                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12750            }
12751            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12752        }
12753    }
12754
12755    public boolean killPids(int[] pids, String pReason, boolean secure) {
12756        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12757            throw new SecurityException("killPids only available to the system");
12758        }
12759        String reason = (pReason == null) ? "Unknown" : pReason;
12760        // XXX Note: don't acquire main activity lock here, because the window
12761        // manager calls in with its locks held.
12762
12763        boolean killed = false;
12764        synchronized (mPidsSelfLocked) {
12765            int worstType = 0;
12766            for (int i=0; i<pids.length; i++) {
12767                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12768                if (proc != null) {
12769                    int type = proc.setAdj;
12770                    if (type > worstType) {
12771                        worstType = type;
12772                    }
12773                }
12774            }
12775
12776            // If the worst oom_adj is somewhere in the cached proc LRU range,
12777            // then constrain it so we will kill all cached procs.
12778            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12779                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12780                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12781            }
12782
12783            // If this is not a secure call, don't let it kill processes that
12784            // are important.
12785            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12786                worstType = ProcessList.SERVICE_ADJ;
12787            }
12788
12789            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12790            for (int i=0; i<pids.length; i++) {
12791                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12792                if (proc == null) {
12793                    continue;
12794                }
12795                int adj = proc.setAdj;
12796                if (adj >= worstType && !proc.killedByAm) {
12797                    proc.kill(reason, true);
12798                    killed = true;
12799                }
12800            }
12801        }
12802        return killed;
12803    }
12804
12805    @Override
12806    public void killUid(int appId, int userId, String reason) {
12807        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12808        synchronized (this) {
12809            final long identity = Binder.clearCallingIdentity();
12810            try {
12811                killPackageProcessesLocked(null, appId, userId,
12812                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12813                        reason != null ? reason : "kill uid");
12814            } finally {
12815                Binder.restoreCallingIdentity(identity);
12816            }
12817        }
12818    }
12819
12820    @Override
12821    public boolean killProcessesBelowForeground(String reason) {
12822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12823            throw new SecurityException("killProcessesBelowForeground() only available to system");
12824        }
12825
12826        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12827    }
12828
12829    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12830        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12831            throw new SecurityException("killProcessesBelowAdj() only available to system");
12832        }
12833
12834        boolean killed = false;
12835        synchronized (mPidsSelfLocked) {
12836            final int size = mPidsSelfLocked.size();
12837            for (int i = 0; i < size; i++) {
12838                final int pid = mPidsSelfLocked.keyAt(i);
12839                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12840                if (proc == null) continue;
12841
12842                final int adj = proc.setAdj;
12843                if (adj > belowAdj && !proc.killedByAm) {
12844                    proc.kill(reason, true);
12845                    killed = true;
12846                }
12847            }
12848        }
12849        return killed;
12850    }
12851
12852    @Override
12853    public void hang(final IBinder who, boolean allowRestart) {
12854        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12855                != PackageManager.PERMISSION_GRANTED) {
12856            throw new SecurityException("Requires permission "
12857                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12858        }
12859
12860        final IBinder.DeathRecipient death = new DeathRecipient() {
12861            @Override
12862            public void binderDied() {
12863                synchronized (this) {
12864                    notifyAll();
12865                }
12866            }
12867        };
12868
12869        try {
12870            who.linkToDeath(death, 0);
12871        } catch (RemoteException e) {
12872            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12873            return;
12874        }
12875
12876        synchronized (this) {
12877            Watchdog.getInstance().setAllowRestart(allowRestart);
12878            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12879            synchronized (death) {
12880                while (who.isBinderAlive()) {
12881                    try {
12882                        death.wait();
12883                    } catch (InterruptedException e) {
12884                    }
12885                }
12886            }
12887            Watchdog.getInstance().setAllowRestart(true);
12888        }
12889    }
12890
12891    @Override
12892    public void restart() {
12893        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12894                != PackageManager.PERMISSION_GRANTED) {
12895            throw new SecurityException("Requires permission "
12896                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12897        }
12898
12899        Log.i(TAG, "Sending shutdown broadcast...");
12900
12901        BroadcastReceiver br = new BroadcastReceiver() {
12902            @Override public void onReceive(Context context, Intent intent) {
12903                // Now the broadcast is done, finish up the low-level shutdown.
12904                Log.i(TAG, "Shutting down activity manager...");
12905                shutdown(10000);
12906                Log.i(TAG, "Shutdown complete, restarting!");
12907                Process.killProcess(Process.myPid());
12908                System.exit(10);
12909            }
12910        };
12911
12912        // First send the high-level shut down broadcast.
12913        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12914        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12915        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12916        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12917        mContext.sendOrderedBroadcastAsUser(intent,
12918                UserHandle.ALL, null, br, mHandler, 0, null, null);
12919        */
12920        br.onReceive(mContext, intent);
12921    }
12922
12923    private long getLowRamTimeSinceIdle(long now) {
12924        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12925    }
12926
12927    @Override
12928    public void performIdleMaintenance() {
12929        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12930                != PackageManager.PERMISSION_GRANTED) {
12931            throw new SecurityException("Requires permission "
12932                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12933        }
12934
12935        synchronized (this) {
12936            final long now = SystemClock.uptimeMillis();
12937            final long timeSinceLastIdle = now - mLastIdleTime;
12938            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12939            mLastIdleTime = now;
12940            mLowRamTimeSinceLastIdle = 0;
12941            if (mLowRamStartTime != 0) {
12942                mLowRamStartTime = now;
12943            }
12944
12945            StringBuilder sb = new StringBuilder(128);
12946            sb.append("Idle maintenance over ");
12947            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12948            sb.append(" low RAM for ");
12949            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12950            Slog.i(TAG, sb.toString());
12951
12952            // If at least 1/3 of our time since the last idle period has been spent
12953            // with RAM low, then we want to kill processes.
12954            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12955
12956            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12957                ProcessRecord proc = mLruProcesses.get(i);
12958                if (proc.notCachedSinceIdle) {
12959                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12960                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12961                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12962                        if (doKilling && proc.initialIdlePss != 0
12963                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12964                            sb = new StringBuilder(128);
12965                            sb.append("Kill");
12966                            sb.append(proc.processName);
12967                            sb.append(" in idle maint: pss=");
12968                            sb.append(proc.lastPss);
12969                            sb.append(", swapPss=");
12970                            sb.append(proc.lastSwapPss);
12971                            sb.append(", initialPss=");
12972                            sb.append(proc.initialIdlePss);
12973                            sb.append(", period=");
12974                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12975                            sb.append(", lowRamPeriod=");
12976                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12977                            Slog.wtfQuiet(TAG, sb.toString());
12978                            proc.kill("idle maint (pss " + proc.lastPss
12979                                    + " from " + proc.initialIdlePss + ")", true);
12980                        }
12981                    }
12982                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12983                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12984                    proc.notCachedSinceIdle = true;
12985                    proc.initialIdlePss = 0;
12986                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12987                            mTestPssMode, isSleepingLocked(), now);
12988                }
12989            }
12990
12991            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12992            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12993        }
12994    }
12995
12996    @Override
12997    public void sendIdleJobTrigger() {
12998        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12999                != PackageManager.PERMISSION_GRANTED) {
13000            throw new SecurityException("Requires permission "
13001                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13002        }
13003
13004        final long ident = Binder.clearCallingIdentity();
13005        try {
13006            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13007                    .setPackage("android")
13008                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13009            broadcastIntent(null, intent, null, null, 0, null, null, null,
13010                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13011        } finally {
13012            Binder.restoreCallingIdentity(ident);
13013        }
13014    }
13015
13016    private void retrieveSettings() {
13017        final ContentResolver resolver = mContext.getContentResolver();
13018        final boolean freeformWindowManagement =
13019                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13020                        || Settings.Global.getInt(
13021                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13022        final boolean supportsPictureInPicture =
13023                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13024
13025        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13026        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13027        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13028        final boolean alwaysFinishActivities =
13029                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13030        final boolean lenientBackgroundCheck =
13031                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13032        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13033        final boolean forceResizable = Settings.Global.getInt(
13034                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13035        final boolean supportsLeanbackOnly =
13036                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13037
13038        // Transfer any global setting for forcing RTL layout, into a System Property
13039        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13040
13041        final Configuration configuration = new Configuration();
13042        Settings.System.getConfiguration(resolver, configuration);
13043        if (forceRtl) {
13044            // This will take care of setting the correct layout direction flags
13045            configuration.setLayoutDirection(configuration.locale);
13046        }
13047
13048        synchronized (this) {
13049            mDebugApp = mOrigDebugApp = debugApp;
13050            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13051            mAlwaysFinishActivities = alwaysFinishActivities;
13052            mLenientBackgroundCheck = lenientBackgroundCheck;
13053            mSupportsLeanbackOnly = supportsLeanbackOnly;
13054            mForceResizableActivities = forceResizable;
13055            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13056            if (supportsMultiWindow || forceResizable) {
13057                mSupportsMultiWindow = true;
13058                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13059                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13060            } else {
13061                mSupportsMultiWindow = false;
13062                mSupportsFreeformWindowManagement = false;
13063                mSupportsPictureInPicture = false;
13064            }
13065            // This happens before any activities are started, so we can
13066            // change mConfiguration in-place.
13067            updateConfigurationLocked(configuration, null, true);
13068            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13069                    "Initial config: " + mConfiguration);
13070
13071            // Load resources only after the current configuration has been set.
13072            final Resources res = mContext.getResources();
13073            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13074            mThumbnailWidth = res.getDimensionPixelSize(
13075                    com.android.internal.R.dimen.thumbnail_width);
13076            mThumbnailHeight = res.getDimensionPixelSize(
13077                    com.android.internal.R.dimen.thumbnail_height);
13078            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13079                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13080            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13081                    com.android.internal.R.string.config_appsNotReportingCrashes));
13082            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13083                mFullscreenThumbnailScale = (float) res
13084                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13085                    (float) mConfiguration.screenWidthDp;
13086            } else {
13087                mFullscreenThumbnailScale = res.getFraction(
13088                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13089            }
13090        }
13091    }
13092
13093    public boolean testIsSystemReady() {
13094        // no need to synchronize(this) just to read & return the value
13095        return mSystemReady;
13096    }
13097
13098    public void systemReady(final Runnable goingCallback) {
13099        synchronized(this) {
13100            if (mSystemReady) {
13101                // If we're done calling all the receivers, run the next "boot phase" passed in
13102                // by the SystemServer
13103                if (goingCallback != null) {
13104                    goingCallback.run();
13105                }
13106                return;
13107            }
13108
13109            mLocalDeviceIdleController
13110                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13111
13112            // Make sure we have the current profile info, since it is needed for security checks.
13113            mUserController.onSystemReady();
13114            mRecentTasks.onSystemReadyLocked();
13115            mAppOpsService.systemReady();
13116            mSystemReady = true;
13117        }
13118
13119        ArrayList<ProcessRecord> procsToKill = null;
13120        synchronized(mPidsSelfLocked) {
13121            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13122                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13123                if (!isAllowedWhileBooting(proc.info)){
13124                    if (procsToKill == null) {
13125                        procsToKill = new ArrayList<ProcessRecord>();
13126                    }
13127                    procsToKill.add(proc);
13128                }
13129            }
13130        }
13131
13132        synchronized(this) {
13133            if (procsToKill != null) {
13134                for (int i=procsToKill.size()-1; i>=0; i--) {
13135                    ProcessRecord proc = procsToKill.get(i);
13136                    Slog.i(TAG, "Removing system update proc: " + proc);
13137                    removeProcessLocked(proc, true, false, "system update done");
13138                }
13139            }
13140
13141            // Now that we have cleaned up any update processes, we
13142            // are ready to start launching real processes and know that
13143            // we won't trample on them any more.
13144            mProcessesReady = true;
13145        }
13146
13147        Slog.i(TAG, "System now ready");
13148        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13149            SystemClock.uptimeMillis());
13150
13151        synchronized(this) {
13152            // Make sure we have no pre-ready processes sitting around.
13153
13154            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13155                ResolveInfo ri = mContext.getPackageManager()
13156                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13157                                STOCK_PM_FLAGS);
13158                CharSequence errorMsg = null;
13159                if (ri != null) {
13160                    ActivityInfo ai = ri.activityInfo;
13161                    ApplicationInfo app = ai.applicationInfo;
13162                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13163                        mTopAction = Intent.ACTION_FACTORY_TEST;
13164                        mTopData = null;
13165                        mTopComponent = new ComponentName(app.packageName,
13166                                ai.name);
13167                    } else {
13168                        errorMsg = mContext.getResources().getText(
13169                                com.android.internal.R.string.factorytest_not_system);
13170                    }
13171                } else {
13172                    errorMsg = mContext.getResources().getText(
13173                            com.android.internal.R.string.factorytest_no_action);
13174                }
13175                if (errorMsg != null) {
13176                    mTopAction = null;
13177                    mTopData = null;
13178                    mTopComponent = null;
13179                    Message msg = Message.obtain();
13180                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13181                    msg.getData().putCharSequence("msg", errorMsg);
13182                    mUiHandler.sendMessage(msg);
13183                }
13184            }
13185        }
13186
13187        retrieveSettings();
13188        final int currentUserId;
13189        synchronized (this) {
13190            currentUserId = mUserController.getCurrentUserIdLocked();
13191            readGrantedUriPermissionsLocked();
13192        }
13193
13194        if (goingCallback != null) goingCallback.run();
13195
13196        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13197                Integer.toString(currentUserId), currentUserId);
13198        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13199                Integer.toString(currentUserId), currentUserId);
13200        mSystemServiceManager.startUser(currentUserId);
13201
13202        synchronized (this) {
13203            // Only start up encryption-aware persistent apps; once user is
13204            // unlocked we'll come back around and start unaware apps
13205            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13206
13207            // Start up initial activity.
13208            mBooting = true;
13209            // Enable home activity for system user, so that the system can always boot
13210            if (UserManager.isSplitSystemUser()) {
13211                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13212                try {
13213                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13214                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13215                            UserHandle.USER_SYSTEM);
13216                } catch (RemoteException e) {
13217                    throw e.rethrowAsRuntimeException();
13218                }
13219            }
13220            startHomeActivityLocked(currentUserId, "systemReady");
13221
13222            try {
13223                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13224                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13225                            + " data partition or your device will be unstable.");
13226                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13227                }
13228            } catch (RemoteException e) {
13229            }
13230
13231            if (!Build.isBuildConsistent()) {
13232                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13233                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13234            }
13235
13236            long ident = Binder.clearCallingIdentity();
13237            try {
13238                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13239                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13240                        | Intent.FLAG_RECEIVER_FOREGROUND);
13241                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13242                broadcastIntentLocked(null, null, intent,
13243                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13244                        null, false, false, MY_PID, Process.SYSTEM_UID,
13245                        currentUserId);
13246                intent = new Intent(Intent.ACTION_USER_STARTING);
13247                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13248                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13249                broadcastIntentLocked(null, null, intent,
13250                        null, new IIntentReceiver.Stub() {
13251                            @Override
13252                            public void performReceive(Intent intent, int resultCode, String data,
13253                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13254                                    throws RemoteException {
13255                            }
13256                        }, 0, null, null,
13257                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13258                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13259            } catch (Throwable t) {
13260                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13261            } finally {
13262                Binder.restoreCallingIdentity(ident);
13263            }
13264            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13265            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13266        }
13267    }
13268
13269    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13270        synchronized (this) {
13271            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13272        }
13273    }
13274
13275    void skipCurrentReceiverLocked(ProcessRecord app) {
13276        for (BroadcastQueue queue : mBroadcastQueues) {
13277            queue.skipCurrentReceiverLocked(app);
13278        }
13279    }
13280
13281    /**
13282     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13283     * The application process will exit immediately after this call returns.
13284     * @param app object of the crashing app, null for the system server
13285     * @param crashInfo describing the exception
13286     */
13287    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13288        ProcessRecord r = findAppProcess(app, "Crash");
13289        final String processName = app == null ? "system_server"
13290                : (r == null ? "unknown" : r.processName);
13291
13292        handleApplicationCrashInner("crash", r, processName, crashInfo);
13293    }
13294
13295    /* Native crash reporting uses this inner version because it needs to be somewhat
13296     * decoupled from the AM-managed cleanup lifecycle
13297     */
13298    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13299            ApplicationErrorReport.CrashInfo crashInfo) {
13300        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13301                UserHandle.getUserId(Binder.getCallingUid()), processName,
13302                r == null ? -1 : r.info.flags,
13303                crashInfo.exceptionClassName,
13304                crashInfo.exceptionMessage,
13305                crashInfo.throwFileName,
13306                crashInfo.throwLineNumber);
13307
13308        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13309
13310        mAppErrors.crashApplication(r, crashInfo);
13311    }
13312
13313    public void handleApplicationStrictModeViolation(
13314            IBinder app,
13315            int violationMask,
13316            StrictMode.ViolationInfo info) {
13317        ProcessRecord r = findAppProcess(app, "StrictMode");
13318        if (r == null) {
13319            return;
13320        }
13321
13322        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13323            Integer stackFingerprint = info.hashCode();
13324            boolean logIt = true;
13325            synchronized (mAlreadyLoggedViolatedStacks) {
13326                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13327                    logIt = false;
13328                    // TODO: sub-sample into EventLog for these, with
13329                    // the info.durationMillis?  Then we'd get
13330                    // the relative pain numbers, without logging all
13331                    // the stack traces repeatedly.  We'd want to do
13332                    // likewise in the client code, which also does
13333                    // dup suppression, before the Binder call.
13334                } else {
13335                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13336                        mAlreadyLoggedViolatedStacks.clear();
13337                    }
13338                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13339                }
13340            }
13341            if (logIt) {
13342                logStrictModeViolationToDropBox(r, info);
13343            }
13344        }
13345
13346        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13347            AppErrorResult result = new AppErrorResult();
13348            synchronized (this) {
13349                final long origId = Binder.clearCallingIdentity();
13350
13351                Message msg = Message.obtain();
13352                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13353                HashMap<String, Object> data = new HashMap<String, Object>();
13354                data.put("result", result);
13355                data.put("app", r);
13356                data.put("violationMask", violationMask);
13357                data.put("info", info);
13358                msg.obj = data;
13359                mUiHandler.sendMessage(msg);
13360
13361                Binder.restoreCallingIdentity(origId);
13362            }
13363            int res = result.get();
13364            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13365        }
13366    }
13367
13368    // Depending on the policy in effect, there could be a bunch of
13369    // these in quick succession so we try to batch these together to
13370    // minimize disk writes, number of dropbox entries, and maximize
13371    // compression, by having more fewer, larger records.
13372    private void logStrictModeViolationToDropBox(
13373            ProcessRecord process,
13374            StrictMode.ViolationInfo info) {
13375        if (info == null) {
13376            return;
13377        }
13378        final boolean isSystemApp = process == null ||
13379                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13380                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13381        final String processName = process == null ? "unknown" : process.processName;
13382        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13383        final DropBoxManager dbox = (DropBoxManager)
13384                mContext.getSystemService(Context.DROPBOX_SERVICE);
13385
13386        // Exit early if the dropbox isn't configured to accept this report type.
13387        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13388
13389        boolean bufferWasEmpty;
13390        boolean needsFlush;
13391        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13392        synchronized (sb) {
13393            bufferWasEmpty = sb.length() == 0;
13394            appendDropBoxProcessHeaders(process, processName, sb);
13395            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13396            sb.append("System-App: ").append(isSystemApp).append("\n");
13397            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13398            if (info.violationNumThisLoop != 0) {
13399                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13400            }
13401            if (info.numAnimationsRunning != 0) {
13402                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13403            }
13404            if (info.broadcastIntentAction != null) {
13405                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13406            }
13407            if (info.durationMillis != -1) {
13408                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13409            }
13410            if (info.numInstances != -1) {
13411                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13412            }
13413            if (info.tags != null) {
13414                for (String tag : info.tags) {
13415                    sb.append("Span-Tag: ").append(tag).append("\n");
13416                }
13417            }
13418            sb.append("\n");
13419            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13420                sb.append(info.crashInfo.stackTrace);
13421                sb.append("\n");
13422            }
13423            if (info.message != null) {
13424                sb.append(info.message);
13425                sb.append("\n");
13426            }
13427
13428            // Only buffer up to ~64k.  Various logging bits truncate
13429            // things at 128k.
13430            needsFlush = (sb.length() > 64 * 1024);
13431        }
13432
13433        // Flush immediately if the buffer's grown too large, or this
13434        // is a non-system app.  Non-system apps are isolated with a
13435        // different tag & policy and not batched.
13436        //
13437        // Batching is useful during internal testing with
13438        // StrictMode settings turned up high.  Without batching,
13439        // thousands of separate files could be created on boot.
13440        if (!isSystemApp || needsFlush) {
13441            new Thread("Error dump: " + dropboxTag) {
13442                @Override
13443                public void run() {
13444                    String report;
13445                    synchronized (sb) {
13446                        report = sb.toString();
13447                        sb.delete(0, sb.length());
13448                        sb.trimToSize();
13449                    }
13450                    if (report.length() != 0) {
13451                        dbox.addText(dropboxTag, report);
13452                    }
13453                }
13454            }.start();
13455            return;
13456        }
13457
13458        // System app batching:
13459        if (!bufferWasEmpty) {
13460            // An existing dropbox-writing thread is outstanding, so
13461            // we don't need to start it up.  The existing thread will
13462            // catch the buffer appends we just did.
13463            return;
13464        }
13465
13466        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13467        // (After this point, we shouldn't access AMS internal data structures.)
13468        new Thread("Error dump: " + dropboxTag) {
13469            @Override
13470            public void run() {
13471                // 5 second sleep to let stacks arrive and be batched together
13472                try {
13473                    Thread.sleep(5000);  // 5 seconds
13474                } catch (InterruptedException e) {}
13475
13476                String errorReport;
13477                synchronized (mStrictModeBuffer) {
13478                    errorReport = mStrictModeBuffer.toString();
13479                    if (errorReport.length() == 0) {
13480                        return;
13481                    }
13482                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13483                    mStrictModeBuffer.trimToSize();
13484                }
13485                dbox.addText(dropboxTag, errorReport);
13486            }
13487        }.start();
13488    }
13489
13490    /**
13491     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13492     * @param app object of the crashing app, null for the system server
13493     * @param tag reported by the caller
13494     * @param system whether this wtf is coming from the system
13495     * @param crashInfo describing the context of the error
13496     * @return true if the process should exit immediately (WTF is fatal)
13497     */
13498    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13499            final ApplicationErrorReport.CrashInfo crashInfo) {
13500        final int callingUid = Binder.getCallingUid();
13501        final int callingPid = Binder.getCallingPid();
13502
13503        if (system) {
13504            // If this is coming from the system, we could very well have low-level
13505            // system locks held, so we want to do this all asynchronously.  And we
13506            // never want this to become fatal, so there is that too.
13507            mHandler.post(new Runnable() {
13508                @Override public void run() {
13509                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13510                }
13511            });
13512            return false;
13513        }
13514
13515        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13516                crashInfo);
13517
13518        if (r != null && r.pid != Process.myPid() &&
13519                Settings.Global.getInt(mContext.getContentResolver(),
13520                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13521            mAppErrors.crashApplication(r, crashInfo);
13522            return true;
13523        } else {
13524            return false;
13525        }
13526    }
13527
13528    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13529            final ApplicationErrorReport.CrashInfo crashInfo) {
13530        final ProcessRecord r = findAppProcess(app, "WTF");
13531        final String processName = app == null ? "system_server"
13532                : (r == null ? "unknown" : r.processName);
13533
13534        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13535                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13536
13537        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13538
13539        return r;
13540    }
13541
13542    /**
13543     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13544     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13545     */
13546    private ProcessRecord findAppProcess(IBinder app, String reason) {
13547        if (app == null) {
13548            return null;
13549        }
13550
13551        synchronized (this) {
13552            final int NP = mProcessNames.getMap().size();
13553            for (int ip=0; ip<NP; ip++) {
13554                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13555                final int NA = apps.size();
13556                for (int ia=0; ia<NA; ia++) {
13557                    ProcessRecord p = apps.valueAt(ia);
13558                    if (p.thread != null && p.thread.asBinder() == app) {
13559                        return p;
13560                    }
13561                }
13562            }
13563
13564            Slog.w(TAG, "Can't find mystery application for " + reason
13565                    + " from pid=" + Binder.getCallingPid()
13566                    + " uid=" + Binder.getCallingUid() + ": " + app);
13567            return null;
13568        }
13569    }
13570
13571    /**
13572     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13573     * to append various headers to the dropbox log text.
13574     */
13575    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13576            StringBuilder sb) {
13577        // Watchdog thread ends up invoking this function (with
13578        // a null ProcessRecord) to add the stack file to dropbox.
13579        // Do not acquire a lock on this (am) in such cases, as it
13580        // could cause a potential deadlock, if and when watchdog
13581        // is invoked due to unavailability of lock on am and it
13582        // would prevent watchdog from killing system_server.
13583        if (process == null) {
13584            sb.append("Process: ").append(processName).append("\n");
13585            return;
13586        }
13587        // Note: ProcessRecord 'process' is guarded by the service
13588        // instance.  (notably process.pkgList, which could otherwise change
13589        // concurrently during execution of this method)
13590        synchronized (this) {
13591            sb.append("Process: ").append(processName).append("\n");
13592            int flags = process.info.flags;
13593            IPackageManager pm = AppGlobals.getPackageManager();
13594            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13595            for (int ip=0; ip<process.pkgList.size(); ip++) {
13596                String pkg = process.pkgList.keyAt(ip);
13597                sb.append("Package: ").append(pkg);
13598                try {
13599                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13600                    if (pi != null) {
13601                        sb.append(" v").append(pi.versionCode);
13602                        if (pi.versionName != null) {
13603                            sb.append(" (").append(pi.versionName).append(")");
13604                        }
13605                    }
13606                } catch (RemoteException e) {
13607                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13608                }
13609                sb.append("\n");
13610            }
13611        }
13612    }
13613
13614    private static String processClass(ProcessRecord process) {
13615        if (process == null || process.pid == MY_PID) {
13616            return "system_server";
13617        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13618            return "system_app";
13619        } else {
13620            return "data_app";
13621        }
13622    }
13623
13624    private volatile long mWtfClusterStart;
13625    private volatile int mWtfClusterCount;
13626
13627    /**
13628     * Write a description of an error (crash, WTF, ANR) to the drop box.
13629     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13630     * @param process which caused the error, null means the system server
13631     * @param activity which triggered the error, null if unknown
13632     * @param parent activity related to the error, null if unknown
13633     * @param subject line related to the error, null if absent
13634     * @param report in long form describing the error, null if absent
13635     * @param dataFile text file to include in the report, null if none
13636     * @param crashInfo giving an application stack trace, null if absent
13637     */
13638    public void addErrorToDropBox(String eventType,
13639            ProcessRecord process, String processName, ActivityRecord activity,
13640            ActivityRecord parent, String subject,
13641            final String report, final File dataFile,
13642            final ApplicationErrorReport.CrashInfo crashInfo) {
13643        // NOTE -- this must never acquire the ActivityManagerService lock,
13644        // otherwise the watchdog may be prevented from resetting the system.
13645
13646        final String dropboxTag = processClass(process) + "_" + eventType;
13647        final DropBoxManager dbox = (DropBoxManager)
13648                mContext.getSystemService(Context.DROPBOX_SERVICE);
13649
13650        // Exit early if the dropbox isn't configured to accept this report type.
13651        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13652
13653        // Rate-limit how often we're willing to do the heavy lifting below to
13654        // collect and record logs; currently 5 logs per 10 second period.
13655        final long now = SystemClock.elapsedRealtime();
13656        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13657            mWtfClusterStart = now;
13658            mWtfClusterCount = 1;
13659        } else {
13660            if (mWtfClusterCount++ >= 5) return;
13661        }
13662
13663        final StringBuilder sb = new StringBuilder(1024);
13664        appendDropBoxProcessHeaders(process, processName, sb);
13665        if (process != null) {
13666            sb.append("Foreground: ")
13667                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13668                    .append("\n");
13669        }
13670        if (activity != null) {
13671            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13672        }
13673        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13674            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13675        }
13676        if (parent != null && parent != activity) {
13677            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13678        }
13679        if (subject != null) {
13680            sb.append("Subject: ").append(subject).append("\n");
13681        }
13682        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13683        if (Debug.isDebuggerConnected()) {
13684            sb.append("Debugger: Connected\n");
13685        }
13686        sb.append("\n");
13687
13688        // Do the rest in a worker thread to avoid blocking the caller on I/O
13689        // (After this point, we shouldn't access AMS internal data structures.)
13690        Thread worker = new Thread("Error dump: " + dropboxTag) {
13691            @Override
13692            public void run() {
13693                if (report != null) {
13694                    sb.append(report);
13695                }
13696
13697                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13698                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13699                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13700                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13701
13702                if (dataFile != null && maxDataFileSize > 0) {
13703                    try {
13704                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13705                                    "\n\n[[TRUNCATED]]"));
13706                    } catch (IOException e) {
13707                        Slog.e(TAG, "Error reading " + dataFile, e);
13708                    }
13709                }
13710                if (crashInfo != null && crashInfo.stackTrace != null) {
13711                    sb.append(crashInfo.stackTrace);
13712                }
13713
13714                if (lines > 0) {
13715                    sb.append("\n");
13716
13717                    // Merge several logcat streams, and take the last N lines
13718                    InputStreamReader input = null;
13719                    try {
13720                        java.lang.Process logcat = new ProcessBuilder(
13721                                "/system/bin/timeout", "-k", "15s", "10s",
13722                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13723                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13724                                        .redirectErrorStream(true).start();
13725
13726                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13727                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13728                        input = new InputStreamReader(logcat.getInputStream());
13729
13730                        int num;
13731                        char[] buf = new char[8192];
13732                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13733                    } catch (IOException e) {
13734                        Slog.e(TAG, "Error running logcat", e);
13735                    } finally {
13736                        if (input != null) try { input.close(); } catch (IOException e) {}
13737                    }
13738                }
13739
13740                dbox.addText(dropboxTag, sb.toString());
13741            }
13742        };
13743
13744        if (process == null) {
13745            // If process is null, we are being called from some internal code
13746            // and may be about to die -- run this synchronously.
13747            worker.run();
13748        } else {
13749            worker.start();
13750        }
13751    }
13752
13753    @Override
13754    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13755        enforceNotIsolatedCaller("getProcessesInErrorState");
13756        // assume our apps are happy - lazy create the list
13757        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13758
13759        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13760                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13761        int userId = UserHandle.getUserId(Binder.getCallingUid());
13762
13763        synchronized (this) {
13764
13765            // iterate across all processes
13766            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13767                ProcessRecord app = mLruProcesses.get(i);
13768                if (!allUsers && app.userId != userId) {
13769                    continue;
13770                }
13771                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13772                    // This one's in trouble, so we'll generate a report for it
13773                    // crashes are higher priority (in case there's a crash *and* an anr)
13774                    ActivityManager.ProcessErrorStateInfo report = null;
13775                    if (app.crashing) {
13776                        report = app.crashingReport;
13777                    } else if (app.notResponding) {
13778                        report = app.notRespondingReport;
13779                    }
13780
13781                    if (report != null) {
13782                        if (errList == null) {
13783                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13784                        }
13785                        errList.add(report);
13786                    } else {
13787                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13788                                " crashing = " + app.crashing +
13789                                " notResponding = " + app.notResponding);
13790                    }
13791                }
13792            }
13793        }
13794
13795        return errList;
13796    }
13797
13798    static int procStateToImportance(int procState, int memAdj,
13799            ActivityManager.RunningAppProcessInfo currApp) {
13800        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13801        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13802            currApp.lru = memAdj;
13803        } else {
13804            currApp.lru = 0;
13805        }
13806        return imp;
13807    }
13808
13809    private void fillInProcMemInfo(ProcessRecord app,
13810            ActivityManager.RunningAppProcessInfo outInfo) {
13811        outInfo.pid = app.pid;
13812        outInfo.uid = app.info.uid;
13813        if (mHeavyWeightProcess == app) {
13814            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13815        }
13816        if (app.persistent) {
13817            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13818        }
13819        if (app.activities.size() > 0) {
13820            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13821        }
13822        outInfo.lastTrimLevel = app.trimMemoryLevel;
13823        int adj = app.curAdj;
13824        int procState = app.curProcState;
13825        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13826        outInfo.importanceReasonCode = app.adjTypeCode;
13827        outInfo.processState = app.curProcState;
13828    }
13829
13830    @Override
13831    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13832        enforceNotIsolatedCaller("getRunningAppProcesses");
13833
13834        final int callingUid = Binder.getCallingUid();
13835
13836        // Lazy instantiation of list
13837        List<ActivityManager.RunningAppProcessInfo> runList = null;
13838        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13839                callingUid) == PackageManager.PERMISSION_GRANTED;
13840        final int userId = UserHandle.getUserId(callingUid);
13841        final boolean allUids = isGetTasksAllowed(
13842                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13843
13844        synchronized (this) {
13845            // Iterate across all processes
13846            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13847                ProcessRecord app = mLruProcesses.get(i);
13848                if ((!allUsers && app.userId != userId)
13849                        || (!allUids && app.uid != callingUid)) {
13850                    continue;
13851                }
13852                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13853                    // Generate process state info for running application
13854                    ActivityManager.RunningAppProcessInfo currApp =
13855                        new ActivityManager.RunningAppProcessInfo(app.processName,
13856                                app.pid, app.getPackageList());
13857                    fillInProcMemInfo(app, currApp);
13858                    if (app.adjSource instanceof ProcessRecord) {
13859                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13860                        currApp.importanceReasonImportance =
13861                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13862                                        app.adjSourceProcState);
13863                    } else if (app.adjSource instanceof ActivityRecord) {
13864                        ActivityRecord r = (ActivityRecord)app.adjSource;
13865                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13866                    }
13867                    if (app.adjTarget instanceof ComponentName) {
13868                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13869                    }
13870                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13871                    //        + " lru=" + currApp.lru);
13872                    if (runList == null) {
13873                        runList = new ArrayList<>();
13874                    }
13875                    runList.add(currApp);
13876                }
13877            }
13878        }
13879        return runList;
13880    }
13881
13882    @Override
13883    public List<ApplicationInfo> getRunningExternalApplications() {
13884        enforceNotIsolatedCaller("getRunningExternalApplications");
13885        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13886        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13887        if (runningApps != null && runningApps.size() > 0) {
13888            Set<String> extList = new HashSet<String>();
13889            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13890                if (app.pkgList != null) {
13891                    for (String pkg : app.pkgList) {
13892                        extList.add(pkg);
13893                    }
13894                }
13895            }
13896            IPackageManager pm = AppGlobals.getPackageManager();
13897            for (String pkg : extList) {
13898                try {
13899                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13900                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13901                        retList.add(info);
13902                    }
13903                } catch (RemoteException e) {
13904                }
13905            }
13906        }
13907        return retList;
13908    }
13909
13910    @Override
13911    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13912        enforceNotIsolatedCaller("getMyMemoryState");
13913        synchronized (this) {
13914            ProcessRecord proc;
13915            synchronized (mPidsSelfLocked) {
13916                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13917            }
13918            fillInProcMemInfo(proc, outInfo);
13919        }
13920    }
13921
13922    @Override
13923    public int getMemoryTrimLevel() {
13924        enforceNotIsolatedCaller("getMyMemoryState");
13925        synchronized (this) {
13926            return mLastMemoryLevel;
13927        }
13928    }
13929
13930    @Override
13931    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13932            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13933        (new ActivityManagerShellCommand(this, false)).exec(
13934                this, in, out, err, args, resultReceiver);
13935    }
13936
13937    @Override
13938    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13939        if (checkCallingPermission(android.Manifest.permission.DUMP)
13940                != PackageManager.PERMISSION_GRANTED) {
13941            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13942                    + Binder.getCallingPid()
13943                    + ", uid=" + Binder.getCallingUid()
13944                    + " without permission "
13945                    + android.Manifest.permission.DUMP);
13946            return;
13947        }
13948
13949        boolean dumpAll = false;
13950        boolean dumpClient = false;
13951        boolean dumpCheckin = false;
13952        boolean dumpCheckinFormat = false;
13953        String dumpPackage = null;
13954
13955        int opti = 0;
13956        while (opti < args.length) {
13957            String opt = args[opti];
13958            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13959                break;
13960            }
13961            opti++;
13962            if ("-a".equals(opt)) {
13963                dumpAll = true;
13964            } else if ("-c".equals(opt)) {
13965                dumpClient = true;
13966            } else if ("-p".equals(opt)) {
13967                if (opti < args.length) {
13968                    dumpPackage = args[opti];
13969                    opti++;
13970                } else {
13971                    pw.println("Error: -p option requires package argument");
13972                    return;
13973                }
13974                dumpClient = true;
13975            } else if ("--checkin".equals(opt)) {
13976                dumpCheckin = dumpCheckinFormat = true;
13977            } else if ("-C".equals(opt)) {
13978                dumpCheckinFormat = true;
13979            } else if ("-h".equals(opt)) {
13980                ActivityManagerShellCommand.dumpHelp(pw, true);
13981                return;
13982            } else {
13983                pw.println("Unknown argument: " + opt + "; use -h for help");
13984            }
13985        }
13986
13987        long origId = Binder.clearCallingIdentity();
13988        boolean more = false;
13989        // Is the caller requesting to dump a particular piece of data?
13990        if (opti < args.length) {
13991            String cmd = args[opti];
13992            opti++;
13993            if ("activities".equals(cmd) || "a".equals(cmd)) {
13994                synchronized (this) {
13995                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13996                }
13997            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13998                synchronized (this) {
13999                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14000                }
14001            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14002                String[] newArgs;
14003                String name;
14004                if (opti >= args.length) {
14005                    name = null;
14006                    newArgs = EMPTY_STRING_ARRAY;
14007                } else {
14008                    dumpPackage = args[opti];
14009                    opti++;
14010                    newArgs = new String[args.length - opti];
14011                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14012                            args.length - opti);
14013                }
14014                synchronized (this) {
14015                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14016                }
14017            } else if ("broadcast-stats".equals(cmd)) {
14018                String[] newArgs;
14019                String name;
14020                if (opti >= args.length) {
14021                    name = null;
14022                    newArgs = EMPTY_STRING_ARRAY;
14023                } else {
14024                    dumpPackage = args[opti];
14025                    opti++;
14026                    newArgs = new String[args.length - opti];
14027                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14028                            args.length - opti);
14029                }
14030                synchronized (this) {
14031                    if (dumpCheckinFormat) {
14032                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14033                                dumpPackage);
14034                    } else {
14035                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14036                    }
14037                }
14038            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14039                String[] newArgs;
14040                String name;
14041                if (opti >= args.length) {
14042                    name = null;
14043                    newArgs = EMPTY_STRING_ARRAY;
14044                } else {
14045                    dumpPackage = args[opti];
14046                    opti++;
14047                    newArgs = new String[args.length - opti];
14048                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14049                            args.length - opti);
14050                }
14051                synchronized (this) {
14052                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14053                }
14054            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14055                String[] newArgs;
14056                String name;
14057                if (opti >= args.length) {
14058                    name = null;
14059                    newArgs = EMPTY_STRING_ARRAY;
14060                } else {
14061                    dumpPackage = args[opti];
14062                    opti++;
14063                    newArgs = new String[args.length - opti];
14064                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14065                            args.length - opti);
14066                }
14067                synchronized (this) {
14068                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14069                }
14070            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14071                synchronized (this) {
14072                    dumpOomLocked(fd, pw, args, opti, true);
14073                }
14074            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14075                synchronized (this) {
14076                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14077                }
14078            } else if ("provider".equals(cmd)) {
14079                String[] newArgs;
14080                String name;
14081                if (opti >= args.length) {
14082                    name = null;
14083                    newArgs = EMPTY_STRING_ARRAY;
14084                } else {
14085                    name = args[opti];
14086                    opti++;
14087                    newArgs = new String[args.length - opti];
14088                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14089                }
14090                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14091                    pw.println("No providers match: " + name);
14092                    pw.println("Use -h for help.");
14093                }
14094            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14095                synchronized (this) {
14096                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14097                }
14098            } else if ("service".equals(cmd)) {
14099                String[] newArgs;
14100                String name;
14101                if (opti >= args.length) {
14102                    name = null;
14103                    newArgs = EMPTY_STRING_ARRAY;
14104                } else {
14105                    name = args[opti];
14106                    opti++;
14107                    newArgs = new String[args.length - opti];
14108                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14109                            args.length - opti);
14110                }
14111                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14112                    pw.println("No services match: " + name);
14113                    pw.println("Use -h for help.");
14114                }
14115            } else if ("package".equals(cmd)) {
14116                String[] newArgs;
14117                if (opti >= args.length) {
14118                    pw.println("package: no package name specified");
14119                    pw.println("Use -h for help.");
14120                } else {
14121                    dumpPackage = args[opti];
14122                    opti++;
14123                    newArgs = new String[args.length - opti];
14124                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14125                            args.length - opti);
14126                    args = newArgs;
14127                    opti = 0;
14128                    more = true;
14129                }
14130            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14131                synchronized (this) {
14132                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14133                }
14134            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14135                if (dumpClient) {
14136                    ActiveServices.ServiceDumper dumper;
14137                    synchronized (this) {
14138                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14139                                dumpPackage);
14140                    }
14141                    dumper.dumpWithClient();
14142                } else {
14143                    synchronized (this) {
14144                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14145                                dumpPackage).dumpLocked();
14146                    }
14147                }
14148            } else if ("locks".equals(cmd)) {
14149                LockGuard.dump(fd, pw, args);
14150            } else {
14151                // Dumping a single activity?
14152                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14153                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14154                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14155                    if (res < 0) {
14156                        pw.println("Bad activity command, or no activities match: " + cmd);
14157                        pw.println("Use -h for help.");
14158                    }
14159                }
14160            }
14161            if (!more) {
14162                Binder.restoreCallingIdentity(origId);
14163                return;
14164            }
14165        }
14166
14167        // No piece of data specified, dump everything.
14168        if (dumpCheckinFormat) {
14169            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14170        } else if (dumpClient) {
14171            ActiveServices.ServiceDumper sdumper;
14172            synchronized (this) {
14173                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14174                pw.println();
14175                if (dumpAll) {
14176                    pw.println("-------------------------------------------------------------------------------");
14177                }
14178                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14179                pw.println();
14180                if (dumpAll) {
14181                    pw.println("-------------------------------------------------------------------------------");
14182                }
14183                if (dumpAll || dumpPackage != null) {
14184                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14185                    pw.println();
14186                    if (dumpAll) {
14187                        pw.println("-------------------------------------------------------------------------------");
14188                    }
14189                }
14190                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14191                pw.println();
14192                if (dumpAll) {
14193                    pw.println("-------------------------------------------------------------------------------");
14194                }
14195                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14196                pw.println();
14197                if (dumpAll) {
14198                    pw.println("-------------------------------------------------------------------------------");
14199                }
14200                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14201                        dumpPackage);
14202            }
14203            sdumper.dumpWithClient();
14204            pw.println();
14205            synchronized (this) {
14206                if (dumpAll) {
14207                    pw.println("-------------------------------------------------------------------------------");
14208                }
14209                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14210                pw.println();
14211                if (dumpAll) {
14212                    pw.println("-------------------------------------------------------------------------------");
14213                }
14214                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14215                if (mAssociations.size() > 0) {
14216                    pw.println();
14217                    if (dumpAll) {
14218                        pw.println("-------------------------------------------------------------------------------");
14219                    }
14220                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14221                }
14222                pw.println();
14223                if (dumpAll) {
14224                    pw.println("-------------------------------------------------------------------------------");
14225                }
14226                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14227            }
14228
14229        } else {
14230            synchronized (this) {
14231                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14232                pw.println();
14233                if (dumpAll) {
14234                    pw.println("-------------------------------------------------------------------------------");
14235                }
14236                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14237                pw.println();
14238                if (dumpAll) {
14239                    pw.println("-------------------------------------------------------------------------------");
14240                }
14241                if (dumpAll || dumpPackage != null) {
14242                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14243                    pw.println();
14244                    if (dumpAll) {
14245                        pw.println("-------------------------------------------------------------------------------");
14246                    }
14247                }
14248                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14249                pw.println();
14250                if (dumpAll) {
14251                    pw.println("-------------------------------------------------------------------------------");
14252                }
14253                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14254                pw.println();
14255                if (dumpAll) {
14256                    pw.println("-------------------------------------------------------------------------------");
14257                }
14258                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14259                        .dumpLocked();
14260                pw.println();
14261                if (dumpAll) {
14262                    pw.println("-------------------------------------------------------------------------------");
14263                }
14264                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14265                pw.println();
14266                if (dumpAll) {
14267                    pw.println("-------------------------------------------------------------------------------");
14268                }
14269                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14270                if (mAssociations.size() > 0) {
14271                    pw.println();
14272                    if (dumpAll) {
14273                        pw.println("-------------------------------------------------------------------------------");
14274                    }
14275                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14276                }
14277                pw.println();
14278                if (dumpAll) {
14279                    pw.println("-------------------------------------------------------------------------------");
14280                }
14281                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14282            }
14283        }
14284        Binder.restoreCallingIdentity(origId);
14285    }
14286
14287    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14288            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14289        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14290
14291        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14292                dumpPackage);
14293        boolean needSep = printedAnything;
14294
14295        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14296                dumpPackage, needSep, "  mFocusedActivity: ");
14297        if (printed) {
14298            printedAnything = true;
14299            needSep = false;
14300        }
14301
14302        if (dumpPackage == null) {
14303            if (needSep) {
14304                pw.println();
14305            }
14306            needSep = true;
14307            printedAnything = true;
14308            mStackSupervisor.dump(pw, "  ");
14309        }
14310
14311        if (!printedAnything) {
14312            pw.println("  (nothing)");
14313        }
14314    }
14315
14316    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14317            int opti, boolean dumpAll, String dumpPackage) {
14318        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14319
14320        boolean printedAnything = false;
14321
14322        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14323            boolean printedHeader = false;
14324
14325            final int N = mRecentTasks.size();
14326            for (int i=0; i<N; i++) {
14327                TaskRecord tr = mRecentTasks.get(i);
14328                if (dumpPackage != null) {
14329                    if (tr.realActivity == null ||
14330                            !dumpPackage.equals(tr.realActivity)) {
14331                        continue;
14332                    }
14333                }
14334                if (!printedHeader) {
14335                    pw.println("  Recent tasks:");
14336                    printedHeader = true;
14337                    printedAnything = true;
14338                }
14339                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14340                        pw.println(tr);
14341                if (dumpAll) {
14342                    mRecentTasks.get(i).dump(pw, "    ");
14343                }
14344            }
14345        }
14346
14347        if (!printedAnything) {
14348            pw.println("  (nothing)");
14349        }
14350    }
14351
14352    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14353            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14354        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14355
14356        int dumpUid = 0;
14357        if (dumpPackage != null) {
14358            IPackageManager pm = AppGlobals.getPackageManager();
14359            try {
14360                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14361            } catch (RemoteException e) {
14362            }
14363        }
14364
14365        boolean printedAnything = false;
14366
14367        final long now = SystemClock.uptimeMillis();
14368
14369        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14370            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14371                    = mAssociations.valueAt(i1);
14372            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14373                SparseArray<ArrayMap<String, Association>> sourceUids
14374                        = targetComponents.valueAt(i2);
14375                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14376                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14377                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14378                        Association ass = sourceProcesses.valueAt(i4);
14379                        if (dumpPackage != null) {
14380                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14381                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14382                                continue;
14383                            }
14384                        }
14385                        printedAnything = true;
14386                        pw.print("  ");
14387                        pw.print(ass.mTargetProcess);
14388                        pw.print("/");
14389                        UserHandle.formatUid(pw, ass.mTargetUid);
14390                        pw.print(" <- ");
14391                        pw.print(ass.mSourceProcess);
14392                        pw.print("/");
14393                        UserHandle.formatUid(pw, ass.mSourceUid);
14394                        pw.println();
14395                        pw.print("    via ");
14396                        pw.print(ass.mTargetComponent.flattenToShortString());
14397                        pw.println();
14398                        pw.print("    ");
14399                        long dur = ass.mTime;
14400                        if (ass.mNesting > 0) {
14401                            dur += now - ass.mStartTime;
14402                        }
14403                        TimeUtils.formatDuration(dur, pw);
14404                        pw.print(" (");
14405                        pw.print(ass.mCount);
14406                        pw.print(" times)");
14407                        pw.print("  ");
14408                        for (int i=0; i<ass.mStateTimes.length; i++) {
14409                            long amt = ass.mStateTimes[i];
14410                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14411                                amt += now - ass.mLastStateUptime;
14412                            }
14413                            if (amt != 0) {
14414                                pw.print(" ");
14415                                pw.print(ProcessList.makeProcStateString(
14416                                            i + ActivityManager.MIN_PROCESS_STATE));
14417                                pw.print("=");
14418                                TimeUtils.formatDuration(amt, pw);
14419                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14420                                    pw.print("*");
14421                                }
14422                            }
14423                        }
14424                        pw.println();
14425                        if (ass.mNesting > 0) {
14426                            pw.print("    Currently active: ");
14427                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14428                            pw.println();
14429                        }
14430                    }
14431                }
14432            }
14433
14434        }
14435
14436        if (!printedAnything) {
14437            pw.println("  (nothing)");
14438        }
14439    }
14440
14441    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14442            String header, boolean needSep) {
14443        boolean printed = false;
14444        int whichAppId = -1;
14445        if (dumpPackage != null) {
14446            try {
14447                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14448                        dumpPackage, 0);
14449                whichAppId = UserHandle.getAppId(info.uid);
14450            } catch (NameNotFoundException e) {
14451                e.printStackTrace();
14452            }
14453        }
14454        for (int i=0; i<uids.size(); i++) {
14455            UidRecord uidRec = uids.valueAt(i);
14456            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14457                continue;
14458            }
14459            if (!printed) {
14460                printed = true;
14461                if (needSep) {
14462                    pw.println();
14463                }
14464                pw.print("  ");
14465                pw.println(header);
14466                needSep = true;
14467            }
14468            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14469            pw.print(": "); pw.println(uidRec);
14470        }
14471        return printed;
14472    }
14473
14474    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14475            int opti, boolean dumpAll, String dumpPackage) {
14476        boolean needSep = false;
14477        boolean printedAnything = false;
14478        int numPers = 0;
14479
14480        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14481
14482        if (dumpAll) {
14483            final int NP = mProcessNames.getMap().size();
14484            for (int ip=0; ip<NP; ip++) {
14485                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14486                final int NA = procs.size();
14487                for (int ia=0; ia<NA; ia++) {
14488                    ProcessRecord r = procs.valueAt(ia);
14489                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14490                        continue;
14491                    }
14492                    if (!needSep) {
14493                        pw.println("  All known processes:");
14494                        needSep = true;
14495                        printedAnything = true;
14496                    }
14497                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14498                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14499                        pw.print(" "); pw.println(r);
14500                    r.dump(pw, "    ");
14501                    if (r.persistent) {
14502                        numPers++;
14503                    }
14504                }
14505            }
14506        }
14507
14508        if (mIsolatedProcesses.size() > 0) {
14509            boolean printed = false;
14510            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14511                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14512                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14513                    continue;
14514                }
14515                if (!printed) {
14516                    if (needSep) {
14517                        pw.println();
14518                    }
14519                    pw.println("  Isolated process list (sorted by uid):");
14520                    printedAnything = true;
14521                    printed = true;
14522                    needSep = true;
14523                }
14524                pw.println(String.format("%sIsolated #%2d: %s",
14525                        "    ", i, r.toString()));
14526            }
14527        }
14528
14529        if (mActiveUids.size() > 0) {
14530            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14531                printedAnything = needSep = true;
14532            }
14533        }
14534        if (mValidateUids.size() > 0) {
14535            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14536                printedAnything = needSep = true;
14537            }
14538        }
14539
14540        if (mLruProcesses.size() > 0) {
14541            if (needSep) {
14542                pw.println();
14543            }
14544            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14545                    pw.print(" total, non-act at ");
14546                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14547                    pw.print(", non-svc at ");
14548                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14549                    pw.println("):");
14550            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14551            needSep = true;
14552            printedAnything = true;
14553        }
14554
14555        if (dumpAll || dumpPackage != null) {
14556            synchronized (mPidsSelfLocked) {
14557                boolean printed = false;
14558                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14559                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14560                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14561                        continue;
14562                    }
14563                    if (!printed) {
14564                        if (needSep) pw.println();
14565                        needSep = true;
14566                        pw.println("  PID mappings:");
14567                        printed = true;
14568                        printedAnything = true;
14569                    }
14570                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14571                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14572                }
14573            }
14574        }
14575
14576        if (mForegroundProcesses.size() > 0) {
14577            synchronized (mPidsSelfLocked) {
14578                boolean printed = false;
14579                for (int i=0; i<mForegroundProcesses.size(); i++) {
14580                    ProcessRecord r = mPidsSelfLocked.get(
14581                            mForegroundProcesses.valueAt(i).pid);
14582                    if (dumpPackage != null && (r == null
14583                            || !r.pkgList.containsKey(dumpPackage))) {
14584                        continue;
14585                    }
14586                    if (!printed) {
14587                        if (needSep) pw.println();
14588                        needSep = true;
14589                        pw.println("  Foreground Processes:");
14590                        printed = true;
14591                        printedAnything = true;
14592                    }
14593                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14594                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14595                }
14596            }
14597        }
14598
14599        if (mPersistentStartingProcesses.size() > 0) {
14600            if (needSep) pw.println();
14601            needSep = true;
14602            printedAnything = true;
14603            pw.println("  Persisent processes that are starting:");
14604            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14605                    "Starting Norm", "Restarting PERS", dumpPackage);
14606        }
14607
14608        if (mRemovedProcesses.size() > 0) {
14609            if (needSep) pw.println();
14610            needSep = true;
14611            printedAnything = true;
14612            pw.println("  Processes that are being removed:");
14613            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14614                    "Removed Norm", "Removed PERS", dumpPackage);
14615        }
14616
14617        if (mProcessesOnHold.size() > 0) {
14618            if (needSep) pw.println();
14619            needSep = true;
14620            printedAnything = true;
14621            pw.println("  Processes that are on old until the system is ready:");
14622            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14623                    "OnHold Norm", "OnHold PERS", dumpPackage);
14624        }
14625
14626        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14627
14628        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14629        if (needSep) {
14630            printedAnything = true;
14631        }
14632
14633        if (dumpPackage == null) {
14634            pw.println();
14635            needSep = false;
14636            mUserController.dump(pw, dumpAll);
14637        }
14638        if (mHomeProcess != null && (dumpPackage == null
14639                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14640            if (needSep) {
14641                pw.println();
14642                needSep = false;
14643            }
14644            pw.println("  mHomeProcess: " + mHomeProcess);
14645        }
14646        if (mPreviousProcess != null && (dumpPackage == null
14647                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14648            if (needSep) {
14649                pw.println();
14650                needSep = false;
14651            }
14652            pw.println("  mPreviousProcess: " + mPreviousProcess);
14653        }
14654        if (dumpAll) {
14655            StringBuilder sb = new StringBuilder(128);
14656            sb.append("  mPreviousProcessVisibleTime: ");
14657            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14658            pw.println(sb);
14659        }
14660        if (mHeavyWeightProcess != null && (dumpPackage == null
14661                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14662            if (needSep) {
14663                pw.println();
14664                needSep = false;
14665            }
14666            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14667        }
14668        if (dumpPackage == null) {
14669            pw.println("  mConfiguration: " + mConfiguration);
14670        }
14671        if (dumpAll) {
14672            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14673            if (mCompatModePackages.getPackages().size() > 0) {
14674                boolean printed = false;
14675                for (Map.Entry<String, Integer> entry
14676                        : mCompatModePackages.getPackages().entrySet()) {
14677                    String pkg = entry.getKey();
14678                    int mode = entry.getValue();
14679                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14680                        continue;
14681                    }
14682                    if (!printed) {
14683                        pw.println("  mScreenCompatPackages:");
14684                        printed = true;
14685                    }
14686                    pw.print("    "); pw.print(pkg); pw.print(": ");
14687                            pw.print(mode); pw.println();
14688                }
14689            }
14690        }
14691        if (dumpPackage == null) {
14692            pw.println("  mWakefulness="
14693                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14694            pw.println("  mSleepTokens=" + mSleepTokens);
14695            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14696                    + lockScreenShownToString());
14697            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14698            if (mRunningVoice != null) {
14699                pw.println("  mRunningVoice=" + mRunningVoice);
14700                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14701            }
14702        }
14703        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14704                || mOrigWaitForDebugger) {
14705            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14706                    || dumpPackage.equals(mOrigDebugApp)) {
14707                if (needSep) {
14708                    pw.println();
14709                    needSep = false;
14710                }
14711                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14712                        + " mDebugTransient=" + mDebugTransient
14713                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14714            }
14715        }
14716        if (mCurAppTimeTracker != null) {
14717            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14718        }
14719        if (mMemWatchProcesses.getMap().size() > 0) {
14720            pw.println("  Mem watch processes:");
14721            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14722                    = mMemWatchProcesses.getMap();
14723            for (int i=0; i<procs.size(); i++) {
14724                final String proc = procs.keyAt(i);
14725                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14726                for (int j=0; j<uids.size(); j++) {
14727                    if (needSep) {
14728                        pw.println();
14729                        needSep = false;
14730                    }
14731                    StringBuilder sb = new StringBuilder();
14732                    sb.append("    ").append(proc).append('/');
14733                    UserHandle.formatUid(sb, uids.keyAt(j));
14734                    Pair<Long, String> val = uids.valueAt(j);
14735                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14736                    if (val.second != null) {
14737                        sb.append(", report to ").append(val.second);
14738                    }
14739                    pw.println(sb.toString());
14740                }
14741            }
14742            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14743            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14744            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14745                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14746        }
14747        if (mTrackAllocationApp != null) {
14748            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14749                if (needSep) {
14750                    pw.println();
14751                    needSep = false;
14752                }
14753                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14754            }
14755        }
14756        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14757                || mProfileFd != null) {
14758            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14759                if (needSep) {
14760                    pw.println();
14761                    needSep = false;
14762                }
14763                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14764                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14765                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14766                        + mAutoStopProfiler);
14767                pw.println("  mProfileType=" + mProfileType);
14768            }
14769        }
14770        if (mNativeDebuggingApp != null) {
14771            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14772                if (needSep) {
14773                    pw.println();
14774                    needSep = false;
14775                }
14776                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14777            }
14778        }
14779        if (dumpPackage == null) {
14780            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14781                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14782                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14783            }
14784            if (mController != null) {
14785                pw.println("  mController=" + mController
14786                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14787            }
14788            if (dumpAll) {
14789                pw.println("  Total persistent processes: " + numPers);
14790                pw.println("  mProcessesReady=" + mProcessesReady
14791                        + " mSystemReady=" + mSystemReady
14792                        + " mBooted=" + mBooted
14793                        + " mFactoryTest=" + mFactoryTest);
14794                pw.println("  mBooting=" + mBooting
14795                        + " mCallFinishBooting=" + mCallFinishBooting
14796                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14797                pw.print("  mLastPowerCheckRealtime=");
14798                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14799                        pw.println("");
14800                pw.print("  mLastPowerCheckUptime=");
14801                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14802                        pw.println("");
14803                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14804                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14805                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14806                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14807                        + " (" + mLruProcesses.size() + " total)"
14808                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14809                        + " mNumServiceProcs=" + mNumServiceProcs
14810                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14811                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14812                        + " mLastMemoryLevel=" + mLastMemoryLevel
14813                        + " mLastNumProcesses=" + mLastNumProcesses);
14814                long now = SystemClock.uptimeMillis();
14815                pw.print("  mLastIdleTime=");
14816                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14817                        pw.print(" mLowRamSinceLastIdle=");
14818                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14819                        pw.println();
14820            }
14821        }
14822
14823        if (!printedAnything) {
14824            pw.println("  (nothing)");
14825        }
14826    }
14827
14828    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14829            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14830        if (mProcessesToGc.size() > 0) {
14831            boolean printed = false;
14832            long now = SystemClock.uptimeMillis();
14833            for (int i=0; i<mProcessesToGc.size(); i++) {
14834                ProcessRecord proc = mProcessesToGc.get(i);
14835                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14836                    continue;
14837                }
14838                if (!printed) {
14839                    if (needSep) pw.println();
14840                    needSep = true;
14841                    pw.println("  Processes that are waiting to GC:");
14842                    printed = true;
14843                }
14844                pw.print("    Process "); pw.println(proc);
14845                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14846                        pw.print(", last gced=");
14847                        pw.print(now-proc.lastRequestedGc);
14848                        pw.print(" ms ago, last lowMem=");
14849                        pw.print(now-proc.lastLowMemory);
14850                        pw.println(" ms ago");
14851
14852            }
14853        }
14854        return needSep;
14855    }
14856
14857    void printOomLevel(PrintWriter pw, String name, int adj) {
14858        pw.print("    ");
14859        if (adj >= 0) {
14860            pw.print(' ');
14861            if (adj < 10) pw.print(' ');
14862        } else {
14863            if (adj > -10) pw.print(' ');
14864        }
14865        pw.print(adj);
14866        pw.print(": ");
14867        pw.print(name);
14868        pw.print(" (");
14869        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14870        pw.println(")");
14871    }
14872
14873    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14874            int opti, boolean dumpAll) {
14875        boolean needSep = false;
14876
14877        if (mLruProcesses.size() > 0) {
14878            if (needSep) pw.println();
14879            needSep = true;
14880            pw.println("  OOM levels:");
14881            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14882            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14883            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14884            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14885            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14886            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14887            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14888            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14889            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14890            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14891            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14892            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14893            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14894            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14895
14896            if (needSep) pw.println();
14897            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14898                    pw.print(" total, non-act at ");
14899                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14900                    pw.print(", non-svc at ");
14901                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14902                    pw.println("):");
14903            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14904            needSep = true;
14905        }
14906
14907        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14908
14909        pw.println();
14910        pw.println("  mHomeProcess: " + mHomeProcess);
14911        pw.println("  mPreviousProcess: " + mPreviousProcess);
14912        if (mHeavyWeightProcess != null) {
14913            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14914        }
14915
14916        return true;
14917    }
14918
14919    /**
14920     * There are three ways to call this:
14921     *  - no provider specified: dump all the providers
14922     *  - a flattened component name that matched an existing provider was specified as the
14923     *    first arg: dump that one provider
14924     *  - the first arg isn't the flattened component name of an existing provider:
14925     *    dump all providers whose component contains the first arg as a substring
14926     */
14927    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14928            int opti, boolean dumpAll) {
14929        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14930    }
14931
14932    static class ItemMatcher {
14933        ArrayList<ComponentName> components;
14934        ArrayList<String> strings;
14935        ArrayList<Integer> objects;
14936        boolean all;
14937
14938        ItemMatcher() {
14939            all = true;
14940        }
14941
14942        void build(String name) {
14943            ComponentName componentName = ComponentName.unflattenFromString(name);
14944            if (componentName != null) {
14945                if (components == null) {
14946                    components = new ArrayList<ComponentName>();
14947                }
14948                components.add(componentName);
14949                all = false;
14950            } else {
14951                int objectId = 0;
14952                // Not a '/' separated full component name; maybe an object ID?
14953                try {
14954                    objectId = Integer.parseInt(name, 16);
14955                    if (objects == null) {
14956                        objects = new ArrayList<Integer>();
14957                    }
14958                    objects.add(objectId);
14959                    all = false;
14960                } catch (RuntimeException e) {
14961                    // Not an integer; just do string match.
14962                    if (strings == null) {
14963                        strings = new ArrayList<String>();
14964                    }
14965                    strings.add(name);
14966                    all = false;
14967                }
14968            }
14969        }
14970
14971        int build(String[] args, int opti) {
14972            for (; opti<args.length; opti++) {
14973                String name = args[opti];
14974                if ("--".equals(name)) {
14975                    return opti+1;
14976                }
14977                build(name);
14978            }
14979            return opti;
14980        }
14981
14982        boolean match(Object object, ComponentName comp) {
14983            if (all) {
14984                return true;
14985            }
14986            if (components != null) {
14987                for (int i=0; i<components.size(); i++) {
14988                    if (components.get(i).equals(comp)) {
14989                        return true;
14990                    }
14991                }
14992            }
14993            if (objects != null) {
14994                for (int i=0; i<objects.size(); i++) {
14995                    if (System.identityHashCode(object) == objects.get(i)) {
14996                        return true;
14997                    }
14998                }
14999            }
15000            if (strings != null) {
15001                String flat = comp.flattenToString();
15002                for (int i=0; i<strings.size(); i++) {
15003                    if (flat.contains(strings.get(i))) {
15004                        return true;
15005                    }
15006                }
15007            }
15008            return false;
15009        }
15010    }
15011
15012    /**
15013     * There are three things that cmd can be:
15014     *  - a flattened component name that matches an existing activity
15015     *  - the cmd arg isn't the flattened component name of an existing activity:
15016     *    dump all activity whose component contains the cmd as a substring
15017     *  - A hex number of the ActivityRecord object instance.
15018     */
15019    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15020            int opti, boolean dumpAll) {
15021        ArrayList<ActivityRecord> activities;
15022
15023        synchronized (this) {
15024            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15025        }
15026
15027        if (activities.size() <= 0) {
15028            return false;
15029        }
15030
15031        String[] newArgs = new String[args.length - opti];
15032        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15033
15034        TaskRecord lastTask = null;
15035        boolean needSep = false;
15036        for (int i=activities.size()-1; i>=0; i--) {
15037            ActivityRecord r = activities.get(i);
15038            if (needSep) {
15039                pw.println();
15040            }
15041            needSep = true;
15042            synchronized (this) {
15043                if (lastTask != r.task) {
15044                    lastTask = r.task;
15045                    pw.print("TASK "); pw.print(lastTask.affinity);
15046                            pw.print(" id="); pw.println(lastTask.taskId);
15047                    if (dumpAll) {
15048                        lastTask.dump(pw, "  ");
15049                    }
15050                }
15051            }
15052            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15053        }
15054        return true;
15055    }
15056
15057    /**
15058     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15059     * there is a thread associated with the activity.
15060     */
15061    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15062            final ActivityRecord r, String[] args, boolean dumpAll) {
15063        String innerPrefix = prefix + "  ";
15064        synchronized (this) {
15065            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15066                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15067                    pw.print(" pid=");
15068                    if (r.app != null) pw.println(r.app.pid);
15069                    else pw.println("(not running)");
15070            if (dumpAll) {
15071                r.dump(pw, innerPrefix);
15072            }
15073        }
15074        if (r.app != null && r.app.thread != null) {
15075            // flush anything that is already in the PrintWriter since the thread is going
15076            // to write to the file descriptor directly
15077            pw.flush();
15078            try {
15079                TransferPipe tp = new TransferPipe();
15080                try {
15081                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15082                            r.appToken, innerPrefix, args);
15083                    tp.go(fd);
15084                } finally {
15085                    tp.kill();
15086                }
15087            } catch (IOException e) {
15088                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15089            } catch (RemoteException e) {
15090                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15091            }
15092        }
15093    }
15094
15095    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15096            int opti, boolean dumpAll, String dumpPackage) {
15097        boolean needSep = false;
15098        boolean onlyHistory = false;
15099        boolean printedAnything = false;
15100
15101        if ("history".equals(dumpPackage)) {
15102            if (opti < args.length && "-s".equals(args[opti])) {
15103                dumpAll = false;
15104            }
15105            onlyHistory = true;
15106            dumpPackage = null;
15107        }
15108
15109        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15110        if (!onlyHistory && dumpAll) {
15111            if (mRegisteredReceivers.size() > 0) {
15112                boolean printed = false;
15113                Iterator it = mRegisteredReceivers.values().iterator();
15114                while (it.hasNext()) {
15115                    ReceiverList r = (ReceiverList)it.next();
15116                    if (dumpPackage != null && (r.app == null ||
15117                            !dumpPackage.equals(r.app.info.packageName))) {
15118                        continue;
15119                    }
15120                    if (!printed) {
15121                        pw.println("  Registered Receivers:");
15122                        needSep = true;
15123                        printed = true;
15124                        printedAnything = true;
15125                    }
15126                    pw.print("  * "); pw.println(r);
15127                    r.dump(pw, "    ");
15128                }
15129            }
15130
15131            if (mReceiverResolver.dump(pw, needSep ?
15132                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15133                    "    ", dumpPackage, false, false)) {
15134                needSep = true;
15135                printedAnything = true;
15136            }
15137        }
15138
15139        for (BroadcastQueue q : mBroadcastQueues) {
15140            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15141            printedAnything |= needSep;
15142        }
15143
15144        needSep = true;
15145
15146        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15147            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15148                if (needSep) {
15149                    pw.println();
15150                }
15151                needSep = true;
15152                printedAnything = true;
15153                pw.print("  Sticky broadcasts for user ");
15154                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15155                StringBuilder sb = new StringBuilder(128);
15156                for (Map.Entry<String, ArrayList<Intent>> ent
15157                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15158                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15159                    if (dumpAll) {
15160                        pw.println(":");
15161                        ArrayList<Intent> intents = ent.getValue();
15162                        final int N = intents.size();
15163                        for (int i=0; i<N; i++) {
15164                            sb.setLength(0);
15165                            sb.append("    Intent: ");
15166                            intents.get(i).toShortString(sb, false, true, false, false);
15167                            pw.println(sb.toString());
15168                            Bundle bundle = intents.get(i).getExtras();
15169                            if (bundle != null) {
15170                                pw.print("      ");
15171                                pw.println(bundle.toString());
15172                            }
15173                        }
15174                    } else {
15175                        pw.println("");
15176                    }
15177                }
15178            }
15179        }
15180
15181        if (!onlyHistory && dumpAll) {
15182            pw.println();
15183            for (BroadcastQueue queue : mBroadcastQueues) {
15184                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15185                        + queue.mBroadcastsScheduled);
15186            }
15187            pw.println("  mHandler:");
15188            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15189            needSep = true;
15190            printedAnything = true;
15191        }
15192
15193        if (!printedAnything) {
15194            pw.println("  (nothing)");
15195        }
15196    }
15197
15198    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15199            int opti, boolean dumpAll, String dumpPackage) {
15200        if (mCurBroadcastStats == null) {
15201            return;
15202        }
15203
15204        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15205        final long now = SystemClock.elapsedRealtime();
15206        if (mLastBroadcastStats != null) {
15207            pw.print("  Last stats (from ");
15208            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15209            pw.print(" to ");
15210            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15211            pw.print(", ");
15212            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15213                    - mLastBroadcastStats.mStartUptime, pw);
15214            pw.println(" uptime):");
15215            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15216                pw.println("    (nothing)");
15217            }
15218            pw.println();
15219        }
15220        pw.print("  Current stats (from ");
15221        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15222        pw.print(" to now, ");
15223        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15224                - mCurBroadcastStats.mStartUptime, pw);
15225        pw.println(" uptime):");
15226        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15227            pw.println("    (nothing)");
15228        }
15229    }
15230
15231    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15232            int opti, boolean fullCheckin, String dumpPackage) {
15233        if (mCurBroadcastStats == null) {
15234            return;
15235        }
15236
15237        if (mLastBroadcastStats != null) {
15238            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15239            if (fullCheckin) {
15240                mLastBroadcastStats = null;
15241                return;
15242            }
15243        }
15244        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15245        if (fullCheckin) {
15246            mCurBroadcastStats = null;
15247        }
15248    }
15249
15250    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15251            int opti, boolean dumpAll, String dumpPackage) {
15252        boolean needSep;
15253        boolean printedAnything = false;
15254
15255        ItemMatcher matcher = new ItemMatcher();
15256        matcher.build(args, opti);
15257
15258        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15259
15260        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15261        printedAnything |= needSep;
15262
15263        if (mLaunchingProviders.size() > 0) {
15264            boolean printed = false;
15265            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15266                ContentProviderRecord r = mLaunchingProviders.get(i);
15267                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15268                    continue;
15269                }
15270                if (!printed) {
15271                    if (needSep) pw.println();
15272                    needSep = true;
15273                    pw.println("  Launching content providers:");
15274                    printed = true;
15275                    printedAnything = true;
15276                }
15277                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15278                        pw.println(r);
15279            }
15280        }
15281
15282        if (!printedAnything) {
15283            pw.println("  (nothing)");
15284        }
15285    }
15286
15287    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15288            int opti, boolean dumpAll, String dumpPackage) {
15289        boolean needSep = false;
15290        boolean printedAnything = false;
15291
15292        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15293
15294        if (mGrantedUriPermissions.size() > 0) {
15295            boolean printed = false;
15296            int dumpUid = -2;
15297            if (dumpPackage != null) {
15298                try {
15299                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15300                            MATCH_UNINSTALLED_PACKAGES, 0);
15301                } catch (NameNotFoundException e) {
15302                    dumpUid = -1;
15303                }
15304            }
15305            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15306                int uid = mGrantedUriPermissions.keyAt(i);
15307                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15308                    continue;
15309                }
15310                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15311                if (!printed) {
15312                    if (needSep) pw.println();
15313                    needSep = true;
15314                    pw.println("  Granted Uri Permissions:");
15315                    printed = true;
15316                    printedAnything = true;
15317                }
15318                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15319                for (UriPermission perm : perms.values()) {
15320                    pw.print("    "); pw.println(perm);
15321                    if (dumpAll) {
15322                        perm.dump(pw, "      ");
15323                    }
15324                }
15325            }
15326        }
15327
15328        if (!printedAnything) {
15329            pw.println("  (nothing)");
15330        }
15331    }
15332
15333    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15334            int opti, boolean dumpAll, String dumpPackage) {
15335        boolean printed = false;
15336
15337        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15338
15339        if (mIntentSenderRecords.size() > 0) {
15340            Iterator<WeakReference<PendingIntentRecord>> it
15341                    = mIntentSenderRecords.values().iterator();
15342            while (it.hasNext()) {
15343                WeakReference<PendingIntentRecord> ref = it.next();
15344                PendingIntentRecord rec = ref != null ? ref.get(): null;
15345                if (dumpPackage != null && (rec == null
15346                        || !dumpPackage.equals(rec.key.packageName))) {
15347                    continue;
15348                }
15349                printed = true;
15350                if (rec != null) {
15351                    pw.print("  * "); pw.println(rec);
15352                    if (dumpAll) {
15353                        rec.dump(pw, "    ");
15354                    }
15355                } else {
15356                    pw.print("  * "); pw.println(ref);
15357                }
15358            }
15359        }
15360
15361        if (!printed) {
15362            pw.println("  (nothing)");
15363        }
15364    }
15365
15366    private static final int dumpProcessList(PrintWriter pw,
15367            ActivityManagerService service, List list,
15368            String prefix, String normalLabel, String persistentLabel,
15369            String dumpPackage) {
15370        int numPers = 0;
15371        final int N = list.size()-1;
15372        for (int i=N; i>=0; i--) {
15373            ProcessRecord r = (ProcessRecord)list.get(i);
15374            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15375                continue;
15376            }
15377            pw.println(String.format("%s%s #%2d: %s",
15378                    prefix, (r.persistent ? persistentLabel : normalLabel),
15379                    i, r.toString()));
15380            if (r.persistent) {
15381                numPers++;
15382            }
15383        }
15384        return numPers;
15385    }
15386
15387    private static final boolean dumpProcessOomList(PrintWriter pw,
15388            ActivityManagerService service, List<ProcessRecord> origList,
15389            String prefix, String normalLabel, String persistentLabel,
15390            boolean inclDetails, String dumpPackage) {
15391
15392        ArrayList<Pair<ProcessRecord, Integer>> list
15393                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15394        for (int i=0; i<origList.size(); i++) {
15395            ProcessRecord r = origList.get(i);
15396            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15397                continue;
15398            }
15399            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15400        }
15401
15402        if (list.size() <= 0) {
15403            return false;
15404        }
15405
15406        Comparator<Pair<ProcessRecord, Integer>> comparator
15407                = new Comparator<Pair<ProcessRecord, Integer>>() {
15408            @Override
15409            public int compare(Pair<ProcessRecord, Integer> object1,
15410                    Pair<ProcessRecord, Integer> object2) {
15411                if (object1.first.setAdj != object2.first.setAdj) {
15412                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15413                }
15414                if (object1.first.setProcState != object2.first.setProcState) {
15415                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15416                }
15417                if (object1.second.intValue() != object2.second.intValue()) {
15418                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15419                }
15420                return 0;
15421            }
15422        };
15423
15424        Collections.sort(list, comparator);
15425
15426        final long curRealtime = SystemClock.elapsedRealtime();
15427        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15428        final long curUptime = SystemClock.uptimeMillis();
15429        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15430
15431        for (int i=list.size()-1; i>=0; i--) {
15432            ProcessRecord r = list.get(i).first;
15433            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15434            char schedGroup;
15435            switch (r.setSchedGroup) {
15436                case ProcessList.SCHED_GROUP_BACKGROUND:
15437                    schedGroup = 'B';
15438                    break;
15439                case ProcessList.SCHED_GROUP_DEFAULT:
15440                    schedGroup = 'F';
15441                    break;
15442                case ProcessList.SCHED_GROUP_TOP_APP:
15443                    schedGroup = 'T';
15444                    break;
15445                default:
15446                    schedGroup = '?';
15447                    break;
15448            }
15449            char foreground;
15450            if (r.foregroundActivities) {
15451                foreground = 'A';
15452            } else if (r.foregroundServices) {
15453                foreground = 'S';
15454            } else {
15455                foreground = ' ';
15456            }
15457            String procState = ProcessList.makeProcStateString(r.curProcState);
15458            pw.print(prefix);
15459            pw.print(r.persistent ? persistentLabel : normalLabel);
15460            pw.print(" #");
15461            int num = (origList.size()-1)-list.get(i).second;
15462            if (num < 10) pw.print(' ');
15463            pw.print(num);
15464            pw.print(": ");
15465            pw.print(oomAdj);
15466            pw.print(' ');
15467            pw.print(schedGroup);
15468            pw.print('/');
15469            pw.print(foreground);
15470            pw.print('/');
15471            pw.print(procState);
15472            pw.print(" trm:");
15473            if (r.trimMemoryLevel < 10) pw.print(' ');
15474            pw.print(r.trimMemoryLevel);
15475            pw.print(' ');
15476            pw.print(r.toShortString());
15477            pw.print(" (");
15478            pw.print(r.adjType);
15479            pw.println(')');
15480            if (r.adjSource != null || r.adjTarget != null) {
15481                pw.print(prefix);
15482                pw.print("    ");
15483                if (r.adjTarget instanceof ComponentName) {
15484                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15485                } else if (r.adjTarget != null) {
15486                    pw.print(r.adjTarget.toString());
15487                } else {
15488                    pw.print("{null}");
15489                }
15490                pw.print("<=");
15491                if (r.adjSource instanceof ProcessRecord) {
15492                    pw.print("Proc{");
15493                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15494                    pw.println("}");
15495                } else if (r.adjSource != null) {
15496                    pw.println(r.adjSource.toString());
15497                } else {
15498                    pw.println("{null}");
15499                }
15500            }
15501            if (inclDetails) {
15502                pw.print(prefix);
15503                pw.print("    ");
15504                pw.print("oom: max="); pw.print(r.maxAdj);
15505                pw.print(" curRaw="); pw.print(r.curRawAdj);
15506                pw.print(" setRaw="); pw.print(r.setRawAdj);
15507                pw.print(" cur="); pw.print(r.curAdj);
15508                pw.print(" set="); pw.println(r.setAdj);
15509                pw.print(prefix);
15510                pw.print("    ");
15511                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15512                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15513                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15514                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15515                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15516                pw.println();
15517                pw.print(prefix);
15518                pw.print("    ");
15519                pw.print("cached="); pw.print(r.cached);
15520                pw.print(" empty="); pw.print(r.empty);
15521                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15522
15523                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15524                    if (r.lastWakeTime != 0) {
15525                        long wtime;
15526                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15527                        synchronized (stats) {
15528                            wtime = stats.getProcessWakeTime(r.info.uid,
15529                                    r.pid, curRealtime);
15530                        }
15531                        long timeUsed = wtime - r.lastWakeTime;
15532                        pw.print(prefix);
15533                        pw.print("    ");
15534                        pw.print("keep awake over ");
15535                        TimeUtils.formatDuration(realtimeSince, pw);
15536                        pw.print(" used ");
15537                        TimeUtils.formatDuration(timeUsed, pw);
15538                        pw.print(" (");
15539                        pw.print((timeUsed*100)/realtimeSince);
15540                        pw.println("%)");
15541                    }
15542                    if (r.lastCpuTime != 0) {
15543                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15544                        pw.print(prefix);
15545                        pw.print("    ");
15546                        pw.print("run cpu over ");
15547                        TimeUtils.formatDuration(uptimeSince, pw);
15548                        pw.print(" used ");
15549                        TimeUtils.formatDuration(timeUsed, pw);
15550                        pw.print(" (");
15551                        pw.print((timeUsed*100)/uptimeSince);
15552                        pw.println("%)");
15553                    }
15554                }
15555            }
15556        }
15557        return true;
15558    }
15559
15560    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15561            String[] args) {
15562        ArrayList<ProcessRecord> procs;
15563        synchronized (this) {
15564            if (args != null && args.length > start
15565                    && args[start].charAt(0) != '-') {
15566                procs = new ArrayList<ProcessRecord>();
15567                int pid = -1;
15568                try {
15569                    pid = Integer.parseInt(args[start]);
15570                } catch (NumberFormatException e) {
15571                }
15572                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15573                    ProcessRecord proc = mLruProcesses.get(i);
15574                    if (proc.pid == pid) {
15575                        procs.add(proc);
15576                    } else if (allPkgs && proc.pkgList != null
15577                            && proc.pkgList.containsKey(args[start])) {
15578                        procs.add(proc);
15579                    } else if (proc.processName.equals(args[start])) {
15580                        procs.add(proc);
15581                    }
15582                }
15583                if (procs.size() <= 0) {
15584                    return null;
15585                }
15586            } else {
15587                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15588            }
15589        }
15590        return procs;
15591    }
15592
15593    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15594            PrintWriter pw, String[] args) {
15595        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15596        if (procs == null) {
15597            pw.println("No process found for: " + args[0]);
15598            return;
15599        }
15600
15601        long uptime = SystemClock.uptimeMillis();
15602        long realtime = SystemClock.elapsedRealtime();
15603        pw.println("Applications Graphics Acceleration Info:");
15604        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15605
15606        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15607            ProcessRecord r = procs.get(i);
15608            if (r.thread != null) {
15609                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15610                pw.flush();
15611                try {
15612                    TransferPipe tp = new TransferPipe();
15613                    try {
15614                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15615                        tp.go(fd);
15616                    } finally {
15617                        tp.kill();
15618                    }
15619                } catch (IOException e) {
15620                    pw.println("Failure while dumping the app: " + r);
15621                    pw.flush();
15622                } catch (RemoteException e) {
15623                    pw.println("Got a RemoteException while dumping the app " + r);
15624                    pw.flush();
15625                }
15626            }
15627        }
15628    }
15629
15630    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15631        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15632        if (procs == null) {
15633            pw.println("No process found for: " + args[0]);
15634            return;
15635        }
15636
15637        pw.println("Applications Database Info:");
15638
15639        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15640            ProcessRecord r = procs.get(i);
15641            if (r.thread != null) {
15642                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15643                pw.flush();
15644                try {
15645                    TransferPipe tp = new TransferPipe();
15646                    try {
15647                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15648                        tp.go(fd);
15649                    } finally {
15650                        tp.kill();
15651                    }
15652                } catch (IOException e) {
15653                    pw.println("Failure while dumping the app: " + r);
15654                    pw.flush();
15655                } catch (RemoteException e) {
15656                    pw.println("Got a RemoteException while dumping the app " + r);
15657                    pw.flush();
15658                }
15659            }
15660        }
15661    }
15662
15663    final static class MemItem {
15664        final boolean isProc;
15665        final String label;
15666        final String shortLabel;
15667        final long pss;
15668        final long swapPss;
15669        final int id;
15670        final boolean hasActivities;
15671        ArrayList<MemItem> subitems;
15672
15673        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15674                boolean _hasActivities) {
15675            isProc = true;
15676            label = _label;
15677            shortLabel = _shortLabel;
15678            pss = _pss;
15679            swapPss = _swapPss;
15680            id = _id;
15681            hasActivities = _hasActivities;
15682        }
15683
15684        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15685            isProc = false;
15686            label = _label;
15687            shortLabel = _shortLabel;
15688            pss = _pss;
15689            swapPss = _swapPss;
15690            id = _id;
15691            hasActivities = false;
15692        }
15693    }
15694
15695    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15696            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15697        if (sort && !isCompact) {
15698            Collections.sort(items, new Comparator<MemItem>() {
15699                @Override
15700                public int compare(MemItem lhs, MemItem rhs) {
15701                    if (lhs.pss < rhs.pss) {
15702                        return 1;
15703                    } else if (lhs.pss > rhs.pss) {
15704                        return -1;
15705                    }
15706                    return 0;
15707                }
15708            });
15709        }
15710
15711        for (int i=0; i<items.size(); i++) {
15712            MemItem mi = items.get(i);
15713            if (!isCompact) {
15714                if (dumpSwapPss) {
15715                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15716                            mi.label, stringifyKBSize(mi.swapPss));
15717                } else {
15718                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15719                }
15720            } else if (mi.isProc) {
15721                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15722                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15723                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15724                pw.println(mi.hasActivities ? ",a" : ",e");
15725            } else {
15726                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15727                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15728            }
15729            if (mi.subitems != null) {
15730                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15731                        true, isCompact, dumpSwapPss);
15732            }
15733        }
15734    }
15735
15736    // These are in KB.
15737    static final long[] DUMP_MEM_BUCKETS = new long[] {
15738        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15739        120*1024, 160*1024, 200*1024,
15740        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15741        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15742    };
15743
15744    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15745            boolean stackLike) {
15746        int start = label.lastIndexOf('.');
15747        if (start >= 0) start++;
15748        else start = 0;
15749        int end = label.length();
15750        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15751            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15752                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15753                out.append(bucket);
15754                out.append(stackLike ? "MB." : "MB ");
15755                out.append(label, start, end);
15756                return;
15757            }
15758        }
15759        out.append(memKB/1024);
15760        out.append(stackLike ? "MB." : "MB ");
15761        out.append(label, start, end);
15762    }
15763
15764    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15765            ProcessList.NATIVE_ADJ,
15766            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15767            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15768            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15769            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15770            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15771            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15772    };
15773    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15774            "Native",
15775            "System", "Persistent", "Persistent Service", "Foreground",
15776            "Visible", "Perceptible",
15777            "Heavy Weight", "Backup",
15778            "A Services", "Home",
15779            "Previous", "B Services", "Cached"
15780    };
15781    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15782            "native",
15783            "sys", "pers", "persvc", "fore",
15784            "vis", "percept",
15785            "heavy", "backup",
15786            "servicea", "home",
15787            "prev", "serviceb", "cached"
15788    };
15789
15790    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15791            long realtime, boolean isCheckinRequest, boolean isCompact) {
15792        if (isCompact) {
15793            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15794        }
15795        if (isCheckinRequest || isCompact) {
15796            // short checkin version
15797            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15798        } else {
15799            pw.println("Applications Memory Usage (in Kilobytes):");
15800            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15801        }
15802    }
15803
15804    private static final int KSM_SHARED = 0;
15805    private static final int KSM_SHARING = 1;
15806    private static final int KSM_UNSHARED = 2;
15807    private static final int KSM_VOLATILE = 3;
15808
15809    private final long[] getKsmInfo() {
15810        long[] longOut = new long[4];
15811        final int[] SINGLE_LONG_FORMAT = new int[] {
15812            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15813        };
15814        long[] longTmp = new long[1];
15815        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15816                SINGLE_LONG_FORMAT, null, longTmp, null);
15817        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15818        longTmp[0] = 0;
15819        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15820                SINGLE_LONG_FORMAT, null, longTmp, null);
15821        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15822        longTmp[0] = 0;
15823        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15824                SINGLE_LONG_FORMAT, null, longTmp, null);
15825        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15826        longTmp[0] = 0;
15827        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15828                SINGLE_LONG_FORMAT, null, longTmp, null);
15829        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15830        return longOut;
15831    }
15832
15833    private static String stringifySize(long size, int order) {
15834        Locale locale = Locale.US;
15835        switch (order) {
15836            case 1:
15837                return String.format(locale, "%,13d", size);
15838            case 1024:
15839                return String.format(locale, "%,9dK", size / 1024);
15840            case 1024 * 1024:
15841                return String.format(locale, "%,5dM", size / 1024 / 1024);
15842            case 1024 * 1024 * 1024:
15843                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15844            default:
15845                throw new IllegalArgumentException("Invalid size order");
15846        }
15847    }
15848
15849    private static String stringifyKBSize(long size) {
15850        return stringifySize(size * 1024, 1024);
15851    }
15852
15853    // Update this version number in case you change the 'compact' format
15854    private static final int MEMINFO_COMPACT_VERSION = 1;
15855
15856    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15857            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15858        boolean dumpDetails = false;
15859        boolean dumpFullDetails = false;
15860        boolean dumpDalvik = false;
15861        boolean dumpSummaryOnly = false;
15862        boolean dumpUnreachable = false;
15863        boolean oomOnly = false;
15864        boolean isCompact = false;
15865        boolean localOnly = false;
15866        boolean packages = false;
15867        boolean isCheckinRequest = false;
15868        boolean dumpSwapPss = false;
15869
15870        int opti = 0;
15871        while (opti < args.length) {
15872            String opt = args[opti];
15873            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15874                break;
15875            }
15876            opti++;
15877            if ("-a".equals(opt)) {
15878                dumpDetails = true;
15879                dumpFullDetails = true;
15880                dumpDalvik = true;
15881                dumpSwapPss = true;
15882            } else if ("-d".equals(opt)) {
15883                dumpDalvik = true;
15884            } else if ("-c".equals(opt)) {
15885                isCompact = true;
15886            } else if ("-s".equals(opt)) {
15887                dumpDetails = true;
15888                dumpSummaryOnly = true;
15889            } else if ("-S".equals(opt)) {
15890                dumpSwapPss = true;
15891            } else if ("--unreachable".equals(opt)) {
15892                dumpUnreachable = true;
15893            } else if ("--oom".equals(opt)) {
15894                oomOnly = true;
15895            } else if ("--local".equals(opt)) {
15896                localOnly = true;
15897            } else if ("--package".equals(opt)) {
15898                packages = true;
15899            } else if ("--checkin".equals(opt)) {
15900                isCheckinRequest = true;
15901
15902            } else if ("-h".equals(opt)) {
15903                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15904                pw.println("  -a: include all available information for each process.");
15905                pw.println("  -d: include dalvik details.");
15906                pw.println("  -c: dump in a compact machine-parseable representation.");
15907                pw.println("  -s: dump only summary of application memory usage.");
15908                pw.println("  -S: dump also SwapPss.");
15909                pw.println("  --oom: only show processes organized by oom adj.");
15910                pw.println("  --local: only collect details locally, don't call process.");
15911                pw.println("  --package: interpret process arg as package, dumping all");
15912                pw.println("             processes that have loaded that package.");
15913                pw.println("  --checkin: dump data for a checkin");
15914                pw.println("If [process] is specified it can be the name or ");
15915                pw.println("pid of a specific process to dump.");
15916                return;
15917            } else {
15918                pw.println("Unknown argument: " + opt + "; use -h for help");
15919            }
15920        }
15921
15922        long uptime = SystemClock.uptimeMillis();
15923        long realtime = SystemClock.elapsedRealtime();
15924        final long[] tmpLong = new long[1];
15925
15926        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15927        if (procs == null) {
15928            // No Java processes.  Maybe they want to print a native process.
15929            if (args != null && args.length > opti
15930                    && args[opti].charAt(0) != '-') {
15931                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15932                        = new ArrayList<ProcessCpuTracker.Stats>();
15933                updateCpuStatsNow();
15934                int findPid = -1;
15935                try {
15936                    findPid = Integer.parseInt(args[opti]);
15937                } catch (NumberFormatException e) {
15938                }
15939                synchronized (mProcessCpuTracker) {
15940                    final int N = mProcessCpuTracker.countStats();
15941                    for (int i=0; i<N; i++) {
15942                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15943                        if (st.pid == findPid || (st.baseName != null
15944                                && st.baseName.equals(args[opti]))) {
15945                            nativeProcs.add(st);
15946                        }
15947                    }
15948                }
15949                if (nativeProcs.size() > 0) {
15950                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15951                            isCompact);
15952                    Debug.MemoryInfo mi = null;
15953                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15954                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15955                        final int pid = r.pid;
15956                        if (!isCheckinRequest && dumpDetails) {
15957                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15958                        }
15959                        if (mi == null) {
15960                            mi = new Debug.MemoryInfo();
15961                        }
15962                        if (dumpDetails || (!brief && !oomOnly)) {
15963                            Debug.getMemoryInfo(pid, mi);
15964                        } else {
15965                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15966                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15967                        }
15968                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15969                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15970                        if (isCheckinRequest) {
15971                            pw.println();
15972                        }
15973                    }
15974                    return;
15975                }
15976            }
15977            pw.println("No process found for: " + args[opti]);
15978            return;
15979        }
15980
15981        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15982            dumpDetails = true;
15983        }
15984
15985        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15986
15987        String[] innerArgs = new String[args.length-opti];
15988        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15989
15990        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15991        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15992        long nativePss = 0;
15993        long nativeSwapPss = 0;
15994        long dalvikPss = 0;
15995        long dalvikSwapPss = 0;
15996        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15997                EmptyArray.LONG;
15998        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15999                EmptyArray.LONG;
16000        long otherPss = 0;
16001        long otherSwapPss = 0;
16002        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16003        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16004
16005        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16006        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16007        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16008                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16009
16010        long totalPss = 0;
16011        long totalSwapPss = 0;
16012        long cachedPss = 0;
16013        long cachedSwapPss = 0;
16014        boolean hasSwapPss = false;
16015
16016        Debug.MemoryInfo mi = null;
16017        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16018            final ProcessRecord r = procs.get(i);
16019            final IApplicationThread thread;
16020            final int pid;
16021            final int oomAdj;
16022            final boolean hasActivities;
16023            synchronized (this) {
16024                thread = r.thread;
16025                pid = r.pid;
16026                oomAdj = r.getSetAdjWithServices();
16027                hasActivities = r.activities.size() > 0;
16028            }
16029            if (thread != null) {
16030                if (!isCheckinRequest && dumpDetails) {
16031                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16032                }
16033                if (mi == null) {
16034                    mi = new Debug.MemoryInfo();
16035                }
16036                if (dumpDetails || (!brief && !oomOnly)) {
16037                    Debug.getMemoryInfo(pid, mi);
16038                    hasSwapPss = mi.hasSwappedOutPss;
16039                } else {
16040                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16041                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16042                }
16043                if (dumpDetails) {
16044                    if (localOnly) {
16045                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16046                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16047                        if (isCheckinRequest) {
16048                            pw.println();
16049                        }
16050                    } else {
16051                        try {
16052                            pw.flush();
16053                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16054                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16055                        } catch (RemoteException e) {
16056                            if (!isCheckinRequest) {
16057                                pw.println("Got RemoteException!");
16058                                pw.flush();
16059                            }
16060                        }
16061                    }
16062                }
16063
16064                final long myTotalPss = mi.getTotalPss();
16065                final long myTotalUss = mi.getTotalUss();
16066                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16067
16068                synchronized (this) {
16069                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16070                        // Record this for posterity if the process has been stable.
16071                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16072                    }
16073                }
16074
16075                if (!isCheckinRequest && mi != null) {
16076                    totalPss += myTotalPss;
16077                    totalSwapPss += myTotalSwapPss;
16078                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16079                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16080                            myTotalSwapPss, pid, hasActivities);
16081                    procMems.add(pssItem);
16082                    procMemsMap.put(pid, pssItem);
16083
16084                    nativePss += mi.nativePss;
16085                    nativeSwapPss += mi.nativeSwappedOutPss;
16086                    dalvikPss += mi.dalvikPss;
16087                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16088                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16089                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16090                        dalvikSubitemSwapPss[j] +=
16091                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16092                    }
16093                    otherPss += mi.otherPss;
16094                    otherSwapPss += mi.otherSwappedOutPss;
16095                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16096                        long mem = mi.getOtherPss(j);
16097                        miscPss[j] += mem;
16098                        otherPss -= mem;
16099                        mem = mi.getOtherSwappedOutPss(j);
16100                        miscSwapPss[j] += mem;
16101                        otherSwapPss -= mem;
16102                    }
16103
16104                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16105                        cachedPss += myTotalPss;
16106                        cachedSwapPss += myTotalSwapPss;
16107                    }
16108
16109                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16110                        if (oomIndex == (oomPss.length - 1)
16111                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16112                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16113                            oomPss[oomIndex] += myTotalPss;
16114                            oomSwapPss[oomIndex] += myTotalSwapPss;
16115                            if (oomProcs[oomIndex] == null) {
16116                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16117                            }
16118                            oomProcs[oomIndex].add(pssItem);
16119                            break;
16120                        }
16121                    }
16122                }
16123            }
16124        }
16125
16126        long nativeProcTotalPss = 0;
16127
16128        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16129            // If we are showing aggregations, also look for native processes to
16130            // include so that our aggregations are more accurate.
16131            updateCpuStatsNow();
16132            mi = null;
16133            synchronized (mProcessCpuTracker) {
16134                final int N = mProcessCpuTracker.countStats();
16135                for (int i=0; i<N; i++) {
16136                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16137                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16138                        if (mi == null) {
16139                            mi = new Debug.MemoryInfo();
16140                        }
16141                        if (!brief && !oomOnly) {
16142                            Debug.getMemoryInfo(st.pid, mi);
16143                        } else {
16144                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16145                            mi.nativePrivateDirty = (int)tmpLong[0];
16146                        }
16147
16148                        final long myTotalPss = mi.getTotalPss();
16149                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16150                        totalPss += myTotalPss;
16151                        nativeProcTotalPss += myTotalPss;
16152
16153                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16154                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16155                        procMems.add(pssItem);
16156
16157                        nativePss += mi.nativePss;
16158                        nativeSwapPss += mi.nativeSwappedOutPss;
16159                        dalvikPss += mi.dalvikPss;
16160                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16161                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16162                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16163                            dalvikSubitemSwapPss[j] +=
16164                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16165                        }
16166                        otherPss += mi.otherPss;
16167                        otherSwapPss += mi.otherSwappedOutPss;
16168                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16169                            long mem = mi.getOtherPss(j);
16170                            miscPss[j] += mem;
16171                            otherPss -= mem;
16172                            mem = mi.getOtherSwappedOutPss(j);
16173                            miscSwapPss[j] += mem;
16174                            otherSwapPss -= mem;
16175                        }
16176                        oomPss[0] += myTotalPss;
16177                        oomSwapPss[0] += myTotalSwapPss;
16178                        if (oomProcs[0] == null) {
16179                            oomProcs[0] = new ArrayList<MemItem>();
16180                        }
16181                        oomProcs[0].add(pssItem);
16182                    }
16183                }
16184            }
16185
16186            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16187
16188            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16189            final MemItem dalvikItem =
16190                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16191            if (dalvikSubitemPss.length > 0) {
16192                dalvikItem.subitems = new ArrayList<MemItem>();
16193                for (int j=0; j<dalvikSubitemPss.length; j++) {
16194                    final String name = Debug.MemoryInfo.getOtherLabel(
16195                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16196                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16197                                    dalvikSubitemSwapPss[j], j));
16198                }
16199            }
16200            catMems.add(dalvikItem);
16201            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16202            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16203                String label = Debug.MemoryInfo.getOtherLabel(j);
16204                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16205            }
16206
16207            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16208            for (int j=0; j<oomPss.length; j++) {
16209                if (oomPss[j] != 0) {
16210                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16211                            : DUMP_MEM_OOM_LABEL[j];
16212                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16213                            DUMP_MEM_OOM_ADJ[j]);
16214                    item.subitems = oomProcs[j];
16215                    oomMems.add(item);
16216                }
16217            }
16218
16219            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16220            if (!brief && !oomOnly && !isCompact) {
16221                pw.println();
16222                pw.println("Total PSS by process:");
16223                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16224                pw.println();
16225            }
16226            if (!isCompact) {
16227                pw.println("Total PSS by OOM adjustment:");
16228            }
16229            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16230            if (!brief && !oomOnly) {
16231                PrintWriter out = categoryPw != null ? categoryPw : pw;
16232                if (!isCompact) {
16233                    out.println();
16234                    out.println("Total PSS by category:");
16235                }
16236                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16237            }
16238            if (!isCompact) {
16239                pw.println();
16240            }
16241            MemInfoReader memInfo = new MemInfoReader();
16242            memInfo.readMemInfo();
16243            if (nativeProcTotalPss > 0) {
16244                synchronized (this) {
16245                    final long cachedKb = memInfo.getCachedSizeKb();
16246                    final long freeKb = memInfo.getFreeSizeKb();
16247                    final long zramKb = memInfo.getZramTotalSizeKb();
16248                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16249                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16250                            kernelKb*1024, nativeProcTotalPss*1024);
16251                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16252                            nativeProcTotalPss);
16253                }
16254            }
16255            if (!brief) {
16256                if (!isCompact) {
16257                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16258                    pw.print(" (status ");
16259                    switch (mLastMemoryLevel) {
16260                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16261                            pw.println("normal)");
16262                            break;
16263                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16264                            pw.println("moderate)");
16265                            break;
16266                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16267                            pw.println("low)");
16268                            break;
16269                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16270                            pw.println("critical)");
16271                            break;
16272                        default:
16273                            pw.print(mLastMemoryLevel);
16274                            pw.println(")");
16275                            break;
16276                    }
16277                    pw.print(" Free RAM: ");
16278                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16279                            + memInfo.getFreeSizeKb()));
16280                    pw.print(" (");
16281                    pw.print(stringifyKBSize(cachedPss));
16282                    pw.print(" cached pss + ");
16283                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16284                    pw.print(" cached kernel + ");
16285                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16286                    pw.println(" free)");
16287                } else {
16288                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16289                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16290                            + memInfo.getFreeSizeKb()); pw.print(",");
16291                    pw.println(totalPss - cachedPss);
16292                }
16293            }
16294            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16295                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16296                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16297            if (!isCompact) {
16298                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16299                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16300                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16301                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16302                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16303            } else {
16304                pw.print("lostram,"); pw.println(lostRAM);
16305            }
16306            if (!brief) {
16307                if (memInfo.getZramTotalSizeKb() != 0) {
16308                    if (!isCompact) {
16309                        pw.print("     ZRAM: ");
16310                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16311                                pw.print(" physical used for ");
16312                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16313                                        - memInfo.getSwapFreeSizeKb()));
16314                                pw.print(" in swap (");
16315                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16316                                pw.println(" total swap)");
16317                    } else {
16318                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16319                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16320                                pw.println(memInfo.getSwapFreeSizeKb());
16321                    }
16322                }
16323                final long[] ksm = getKsmInfo();
16324                if (!isCompact) {
16325                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16326                            || ksm[KSM_VOLATILE] != 0) {
16327                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16328                                pw.print(" saved from shared ");
16329                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16330                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16331                                pw.print(" unshared; ");
16332                                pw.print(stringifyKBSize(
16333                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16334                    }
16335                    pw.print("   Tuning: ");
16336                    pw.print(ActivityManager.staticGetMemoryClass());
16337                    pw.print(" (large ");
16338                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16339                    pw.print("), oom ");
16340                    pw.print(stringifySize(
16341                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16342                    pw.print(", restore limit ");
16343                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16344                    if (ActivityManager.isLowRamDeviceStatic()) {
16345                        pw.print(" (low-ram)");
16346                    }
16347                    if (ActivityManager.isHighEndGfx()) {
16348                        pw.print(" (high-end-gfx)");
16349                    }
16350                    pw.println();
16351                } else {
16352                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16353                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16354                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16355                    pw.print("tuning,");
16356                    pw.print(ActivityManager.staticGetMemoryClass());
16357                    pw.print(',');
16358                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16359                    pw.print(',');
16360                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16361                    if (ActivityManager.isLowRamDeviceStatic()) {
16362                        pw.print(",low-ram");
16363                    }
16364                    if (ActivityManager.isHighEndGfx()) {
16365                        pw.print(",high-end-gfx");
16366                    }
16367                    pw.println();
16368                }
16369            }
16370        }
16371    }
16372
16373    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16374            long memtrack, String name) {
16375        sb.append("  ");
16376        sb.append(ProcessList.makeOomAdjString(oomAdj));
16377        sb.append(' ');
16378        sb.append(ProcessList.makeProcStateString(procState));
16379        sb.append(' ');
16380        ProcessList.appendRamKb(sb, pss);
16381        sb.append(": ");
16382        sb.append(name);
16383        if (memtrack > 0) {
16384            sb.append(" (");
16385            sb.append(stringifyKBSize(memtrack));
16386            sb.append(" memtrack)");
16387        }
16388    }
16389
16390    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16391        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16392        sb.append(" (pid ");
16393        sb.append(mi.pid);
16394        sb.append(") ");
16395        sb.append(mi.adjType);
16396        sb.append('\n');
16397        if (mi.adjReason != null) {
16398            sb.append("                      ");
16399            sb.append(mi.adjReason);
16400            sb.append('\n');
16401        }
16402    }
16403
16404    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16405        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16406        for (int i=0, N=memInfos.size(); i<N; i++) {
16407            ProcessMemInfo mi = memInfos.get(i);
16408            infoMap.put(mi.pid, mi);
16409        }
16410        updateCpuStatsNow();
16411        long[] memtrackTmp = new long[1];
16412        synchronized (mProcessCpuTracker) {
16413            final int N = mProcessCpuTracker.countStats();
16414            for (int i=0; i<N; i++) {
16415                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16416                if (st.vsize > 0) {
16417                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16418                    if (pss > 0) {
16419                        if (infoMap.indexOfKey(st.pid) < 0) {
16420                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16421                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16422                            mi.pss = pss;
16423                            mi.memtrack = memtrackTmp[0];
16424                            memInfos.add(mi);
16425                        }
16426                    }
16427                }
16428            }
16429        }
16430
16431        long totalPss = 0;
16432        long totalMemtrack = 0;
16433        for (int i=0, N=memInfos.size(); i<N; i++) {
16434            ProcessMemInfo mi = memInfos.get(i);
16435            if (mi.pss == 0) {
16436                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16437                mi.memtrack = memtrackTmp[0];
16438            }
16439            totalPss += mi.pss;
16440            totalMemtrack += mi.memtrack;
16441        }
16442        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16443            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16444                if (lhs.oomAdj != rhs.oomAdj) {
16445                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16446                }
16447                if (lhs.pss != rhs.pss) {
16448                    return lhs.pss < rhs.pss ? 1 : -1;
16449                }
16450                return 0;
16451            }
16452        });
16453
16454        StringBuilder tag = new StringBuilder(128);
16455        StringBuilder stack = new StringBuilder(128);
16456        tag.append("Low on memory -- ");
16457        appendMemBucket(tag, totalPss, "total", false);
16458        appendMemBucket(stack, totalPss, "total", true);
16459
16460        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16461        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16462        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16463
16464        boolean firstLine = true;
16465        int lastOomAdj = Integer.MIN_VALUE;
16466        long extraNativeRam = 0;
16467        long extraNativeMemtrack = 0;
16468        long cachedPss = 0;
16469        for (int i=0, N=memInfos.size(); i<N; i++) {
16470            ProcessMemInfo mi = memInfos.get(i);
16471
16472            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16473                cachedPss += mi.pss;
16474            }
16475
16476            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16477                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16478                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16479                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16480                if (lastOomAdj != mi.oomAdj) {
16481                    lastOomAdj = mi.oomAdj;
16482                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16483                        tag.append(" / ");
16484                    }
16485                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16486                        if (firstLine) {
16487                            stack.append(":");
16488                            firstLine = false;
16489                        }
16490                        stack.append("\n\t at ");
16491                    } else {
16492                        stack.append("$");
16493                    }
16494                } else {
16495                    tag.append(" ");
16496                    stack.append("$");
16497                }
16498                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16499                    appendMemBucket(tag, mi.pss, mi.name, false);
16500                }
16501                appendMemBucket(stack, mi.pss, mi.name, true);
16502                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16503                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16504                    stack.append("(");
16505                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16506                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16507                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16508                            stack.append(":");
16509                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16510                        }
16511                    }
16512                    stack.append(")");
16513                }
16514            }
16515
16516            appendMemInfo(fullNativeBuilder, mi);
16517            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16518                // The short form only has native processes that are >= 512K.
16519                if (mi.pss >= 512) {
16520                    appendMemInfo(shortNativeBuilder, mi);
16521                } else {
16522                    extraNativeRam += mi.pss;
16523                    extraNativeMemtrack += mi.memtrack;
16524                }
16525            } else {
16526                // Short form has all other details, but if we have collected RAM
16527                // from smaller native processes let's dump a summary of that.
16528                if (extraNativeRam > 0) {
16529                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16530                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16531                    shortNativeBuilder.append('\n');
16532                    extraNativeRam = 0;
16533                }
16534                appendMemInfo(fullJavaBuilder, mi);
16535            }
16536        }
16537
16538        fullJavaBuilder.append("           ");
16539        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16540        fullJavaBuilder.append(": TOTAL");
16541        if (totalMemtrack > 0) {
16542            fullJavaBuilder.append(" (");
16543            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16544            fullJavaBuilder.append(" memtrack)");
16545        } else {
16546        }
16547        fullJavaBuilder.append("\n");
16548
16549        MemInfoReader memInfo = new MemInfoReader();
16550        memInfo.readMemInfo();
16551        final long[] infos = memInfo.getRawInfo();
16552
16553        StringBuilder memInfoBuilder = new StringBuilder(1024);
16554        Debug.getMemInfo(infos);
16555        memInfoBuilder.append("  MemInfo: ");
16556        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16557        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16558        memInfoBuilder.append(stringifyKBSize(
16559                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16560        memInfoBuilder.append(stringifyKBSize(
16561                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16562        memInfoBuilder.append(stringifyKBSize(
16563                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16564        memInfoBuilder.append("           ");
16565        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16566        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16567        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16568        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16569        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16570            memInfoBuilder.append("  ZRAM: ");
16571            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16572            memInfoBuilder.append(" RAM, ");
16573            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16574            memInfoBuilder.append(" swap total, ");
16575            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16576            memInfoBuilder.append(" swap free\n");
16577        }
16578        final long[] ksm = getKsmInfo();
16579        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16580                || ksm[KSM_VOLATILE] != 0) {
16581            memInfoBuilder.append("  KSM: ");
16582            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16583            memInfoBuilder.append(" saved from shared ");
16584            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16585            memInfoBuilder.append("\n       ");
16586            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16587            memInfoBuilder.append(" unshared; ");
16588            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16589            memInfoBuilder.append(" volatile\n");
16590        }
16591        memInfoBuilder.append("  Free RAM: ");
16592        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16593                + memInfo.getFreeSizeKb()));
16594        memInfoBuilder.append("\n");
16595        memInfoBuilder.append("  Used RAM: ");
16596        memInfoBuilder.append(stringifyKBSize(
16597                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16598        memInfoBuilder.append("\n");
16599        memInfoBuilder.append("  Lost RAM: ");
16600        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16601                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16602                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16603        memInfoBuilder.append("\n");
16604        Slog.i(TAG, "Low on memory:");
16605        Slog.i(TAG, shortNativeBuilder.toString());
16606        Slog.i(TAG, fullJavaBuilder.toString());
16607        Slog.i(TAG, memInfoBuilder.toString());
16608
16609        StringBuilder dropBuilder = new StringBuilder(1024);
16610        /*
16611        StringWriter oomSw = new StringWriter();
16612        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16613        StringWriter catSw = new StringWriter();
16614        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16615        String[] emptyArgs = new String[] { };
16616        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16617        oomPw.flush();
16618        String oomString = oomSw.toString();
16619        */
16620        dropBuilder.append("Low on memory:");
16621        dropBuilder.append(stack);
16622        dropBuilder.append('\n');
16623        dropBuilder.append(fullNativeBuilder);
16624        dropBuilder.append(fullJavaBuilder);
16625        dropBuilder.append('\n');
16626        dropBuilder.append(memInfoBuilder);
16627        dropBuilder.append('\n');
16628        /*
16629        dropBuilder.append(oomString);
16630        dropBuilder.append('\n');
16631        */
16632        StringWriter catSw = new StringWriter();
16633        synchronized (ActivityManagerService.this) {
16634            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16635            String[] emptyArgs = new String[] { };
16636            catPw.println();
16637            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16638            catPw.println();
16639            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16640                    false, null).dumpLocked();
16641            catPw.println();
16642            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16643            catPw.flush();
16644        }
16645        dropBuilder.append(catSw.toString());
16646        addErrorToDropBox("lowmem", null, "system_server", null,
16647                null, tag.toString(), dropBuilder.toString(), null, null);
16648        //Slog.i(TAG, "Sent to dropbox:");
16649        //Slog.i(TAG, dropBuilder.toString());
16650        synchronized (ActivityManagerService.this) {
16651            long now = SystemClock.uptimeMillis();
16652            if (mLastMemUsageReportTime < now) {
16653                mLastMemUsageReportTime = now;
16654            }
16655        }
16656    }
16657
16658    /**
16659     * Searches array of arguments for the specified string
16660     * @param args array of argument strings
16661     * @param value value to search for
16662     * @return true if the value is contained in the array
16663     */
16664    private static boolean scanArgs(String[] args, String value) {
16665        if (args != null) {
16666            for (String arg : args) {
16667                if (value.equals(arg)) {
16668                    return true;
16669                }
16670            }
16671        }
16672        return false;
16673    }
16674
16675    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16676            ContentProviderRecord cpr, boolean always) {
16677        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16678
16679        if (!inLaunching || always) {
16680            synchronized (cpr) {
16681                cpr.launchingApp = null;
16682                cpr.notifyAll();
16683            }
16684            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16685            String names[] = cpr.info.authority.split(";");
16686            for (int j = 0; j < names.length; j++) {
16687                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16688            }
16689        }
16690
16691        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16692            ContentProviderConnection conn = cpr.connections.get(i);
16693            if (conn.waiting) {
16694                // If this connection is waiting for the provider, then we don't
16695                // need to mess with its process unless we are always removing
16696                // or for some reason the provider is not currently launching.
16697                if (inLaunching && !always) {
16698                    continue;
16699                }
16700            }
16701            ProcessRecord capp = conn.client;
16702            conn.dead = true;
16703            if (conn.stableCount > 0) {
16704                if (!capp.persistent && capp.thread != null
16705                        && capp.pid != 0
16706                        && capp.pid != MY_PID) {
16707                    capp.kill("depends on provider "
16708                            + cpr.name.flattenToShortString()
16709                            + " in dying proc " + (proc != null ? proc.processName : "??")
16710                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16711                }
16712            } else if (capp.thread != null && conn.provider.provider != null) {
16713                try {
16714                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16715                } catch (RemoteException e) {
16716                }
16717                // In the protocol here, we don't expect the client to correctly
16718                // clean up this connection, we'll just remove it.
16719                cpr.connections.remove(i);
16720                if (conn.client.conProviders.remove(conn)) {
16721                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16722                }
16723            }
16724        }
16725
16726        if (inLaunching && always) {
16727            mLaunchingProviders.remove(cpr);
16728        }
16729        return inLaunching;
16730    }
16731
16732    /**
16733     * Main code for cleaning up a process when it has gone away.  This is
16734     * called both as a result of the process dying, or directly when stopping
16735     * a process when running in single process mode.
16736     *
16737     * @return Returns true if the given process has been restarted, so the
16738     * app that was passed in must remain on the process lists.
16739     */
16740    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16741            boolean restarting, boolean allowRestart, int index) {
16742        if (index >= 0) {
16743            removeLruProcessLocked(app);
16744            ProcessList.remove(app.pid);
16745        }
16746
16747        mProcessesToGc.remove(app);
16748        mPendingPssProcesses.remove(app);
16749
16750        // Dismiss any open dialogs.
16751        if (app.crashDialog != null && !app.forceCrashReport) {
16752            app.crashDialog.dismiss();
16753            app.crashDialog = null;
16754        }
16755        if (app.anrDialog != null) {
16756            app.anrDialog.dismiss();
16757            app.anrDialog = null;
16758        }
16759        if (app.waitDialog != null) {
16760            app.waitDialog.dismiss();
16761            app.waitDialog = null;
16762        }
16763
16764        app.crashing = false;
16765        app.notResponding = false;
16766
16767        app.resetPackageList(mProcessStats);
16768        app.unlinkDeathRecipient();
16769        app.makeInactive(mProcessStats);
16770        app.waitingToKill = null;
16771        app.forcingToForeground = null;
16772        updateProcessForegroundLocked(app, false, false);
16773        app.foregroundActivities = false;
16774        app.hasShownUi = false;
16775        app.treatLikeActivity = false;
16776        app.hasAboveClient = false;
16777        app.hasClientActivities = false;
16778
16779        mServices.killServicesLocked(app, allowRestart);
16780
16781        boolean restart = false;
16782
16783        // Remove published content providers.
16784        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16785            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16786            final boolean always = app.bad || !allowRestart;
16787            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16788            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16789                // We left the provider in the launching list, need to
16790                // restart it.
16791                restart = true;
16792            }
16793
16794            cpr.provider = null;
16795            cpr.proc = null;
16796        }
16797        app.pubProviders.clear();
16798
16799        // Take care of any launching providers waiting for this process.
16800        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16801            restart = true;
16802        }
16803
16804        // Unregister from connected content providers.
16805        if (!app.conProviders.isEmpty()) {
16806            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16807                ContentProviderConnection conn = app.conProviders.get(i);
16808                conn.provider.connections.remove(conn);
16809                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16810                        conn.provider.name);
16811            }
16812            app.conProviders.clear();
16813        }
16814
16815        // At this point there may be remaining entries in mLaunchingProviders
16816        // where we were the only one waiting, so they are no longer of use.
16817        // Look for these and clean up if found.
16818        // XXX Commented out for now.  Trying to figure out a way to reproduce
16819        // the actual situation to identify what is actually going on.
16820        if (false) {
16821            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16822                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16823                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16824                    synchronized (cpr) {
16825                        cpr.launchingApp = null;
16826                        cpr.notifyAll();
16827                    }
16828                }
16829            }
16830        }
16831
16832        skipCurrentReceiverLocked(app);
16833
16834        // Unregister any receivers.
16835        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16836            removeReceiverLocked(app.receivers.valueAt(i));
16837        }
16838        app.receivers.clear();
16839
16840        // If the app is undergoing backup, tell the backup manager about it
16841        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16842            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16843                    + mBackupTarget.appInfo + " died during backup");
16844            try {
16845                IBackupManager bm = IBackupManager.Stub.asInterface(
16846                        ServiceManager.getService(Context.BACKUP_SERVICE));
16847                bm.agentDisconnected(app.info.packageName);
16848            } catch (RemoteException e) {
16849                // can't happen; backup manager is local
16850            }
16851        }
16852
16853        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16854            ProcessChangeItem item = mPendingProcessChanges.get(i);
16855            if (item.pid == app.pid) {
16856                mPendingProcessChanges.remove(i);
16857                mAvailProcessChanges.add(item);
16858            }
16859        }
16860        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16861                null).sendToTarget();
16862
16863        // If the caller is restarting this app, then leave it in its
16864        // current lists and let the caller take care of it.
16865        if (restarting) {
16866            return false;
16867        }
16868
16869        if (!app.persistent || app.isolated) {
16870            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16871                    "Removing non-persistent process during cleanup: " + app);
16872            removeProcessNameLocked(app.processName, app.uid);
16873            if (mHeavyWeightProcess == app) {
16874                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16875                        mHeavyWeightProcess.userId, 0));
16876                mHeavyWeightProcess = null;
16877            }
16878        } else if (!app.removed) {
16879            // This app is persistent, so we need to keep its record around.
16880            // If it is not already on the pending app list, add it there
16881            // and start a new process for it.
16882            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16883                mPersistentStartingProcesses.add(app);
16884                restart = true;
16885            }
16886        }
16887        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16888                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16889        mProcessesOnHold.remove(app);
16890
16891        if (app == mHomeProcess) {
16892            mHomeProcess = null;
16893        }
16894        if (app == mPreviousProcess) {
16895            mPreviousProcess = null;
16896        }
16897
16898        if (restart && !app.isolated) {
16899            // We have components that still need to be running in the
16900            // process, so re-launch it.
16901            if (index < 0) {
16902                ProcessList.remove(app.pid);
16903            }
16904            addProcessNameLocked(app);
16905            startProcessLocked(app, "restart", app.processName);
16906            return true;
16907        } else if (app.pid > 0 && app.pid != MY_PID) {
16908            // Goodbye!
16909            boolean removed;
16910            synchronized (mPidsSelfLocked) {
16911                mPidsSelfLocked.remove(app.pid);
16912                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16913            }
16914            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16915            if (app.isolated) {
16916                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16917            }
16918            app.setPid(0);
16919        }
16920        return false;
16921    }
16922
16923    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16924        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16925            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16926            if (cpr.launchingApp == app) {
16927                return true;
16928            }
16929        }
16930        return false;
16931    }
16932
16933    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16934        // Look through the content providers we are waiting to have launched,
16935        // and if any run in this process then either schedule a restart of
16936        // the process or kill the client waiting for it if this process has
16937        // gone bad.
16938        boolean restart = false;
16939        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16940            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16941            if (cpr.launchingApp == app) {
16942                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16943                    restart = true;
16944                } else {
16945                    removeDyingProviderLocked(app, cpr, true);
16946                }
16947            }
16948        }
16949        return restart;
16950    }
16951
16952    // =========================================================
16953    // SERVICES
16954    // =========================================================
16955
16956    @Override
16957    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16958            int flags) {
16959        enforceNotIsolatedCaller("getServices");
16960        synchronized (this) {
16961            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16962        }
16963    }
16964
16965    @Override
16966    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16967        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16968        synchronized (this) {
16969            return mServices.getRunningServiceControlPanelLocked(name);
16970        }
16971    }
16972
16973    @Override
16974    public ComponentName startService(IApplicationThread caller, Intent service,
16975            String resolvedType, String callingPackage, int userId)
16976            throws TransactionTooLargeException {
16977        enforceNotIsolatedCaller("startService");
16978        // Refuse possible leaked file descriptors
16979        if (service != null && service.hasFileDescriptors() == true) {
16980            throw new IllegalArgumentException("File descriptors passed in Intent");
16981        }
16982
16983        if (callingPackage == null) {
16984            throw new IllegalArgumentException("callingPackage cannot be null");
16985        }
16986
16987        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16988                "startService: " + service + " type=" + resolvedType);
16989        synchronized(this) {
16990            final int callingPid = Binder.getCallingPid();
16991            final int callingUid = Binder.getCallingUid();
16992            final long origId = Binder.clearCallingIdentity();
16993            ComponentName res = mServices.startServiceLocked(caller, service,
16994                    resolvedType, callingPid, callingUid, callingPackage, userId);
16995            Binder.restoreCallingIdentity(origId);
16996            return res;
16997        }
16998    }
16999
17000    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17001            String callingPackage, int userId)
17002            throws TransactionTooLargeException {
17003        synchronized(this) {
17004            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17005                    "startServiceInPackage: " + service + " type=" + resolvedType);
17006            final long origId = Binder.clearCallingIdentity();
17007            ComponentName res = mServices.startServiceLocked(null, service,
17008                    resolvedType, -1, uid, callingPackage, userId);
17009            Binder.restoreCallingIdentity(origId);
17010            return res;
17011        }
17012    }
17013
17014    @Override
17015    public int stopService(IApplicationThread caller, Intent service,
17016            String resolvedType, int userId) {
17017        enforceNotIsolatedCaller("stopService");
17018        // Refuse possible leaked file descriptors
17019        if (service != null && service.hasFileDescriptors() == true) {
17020            throw new IllegalArgumentException("File descriptors passed in Intent");
17021        }
17022
17023        synchronized(this) {
17024            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17025        }
17026    }
17027
17028    @Override
17029    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17030        enforceNotIsolatedCaller("peekService");
17031        // Refuse possible leaked file descriptors
17032        if (service != null && service.hasFileDescriptors() == true) {
17033            throw new IllegalArgumentException("File descriptors passed in Intent");
17034        }
17035
17036        if (callingPackage == null) {
17037            throw new IllegalArgumentException("callingPackage cannot be null");
17038        }
17039
17040        synchronized(this) {
17041            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17042        }
17043    }
17044
17045    @Override
17046    public boolean stopServiceToken(ComponentName className, IBinder token,
17047            int startId) {
17048        synchronized(this) {
17049            return mServices.stopServiceTokenLocked(className, token, startId);
17050        }
17051    }
17052
17053    @Override
17054    public void setServiceForeground(ComponentName className, IBinder token,
17055            int id, Notification notification, int flags) {
17056        synchronized(this) {
17057            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17058        }
17059    }
17060
17061    @Override
17062    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17063            boolean requireFull, String name, String callerPackage) {
17064        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17065                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17066    }
17067
17068    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17069            String className, int flags) {
17070        boolean result = false;
17071        // For apps that don't have pre-defined UIDs, check for permission
17072        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17073            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17074                if (ActivityManager.checkUidPermission(
17075                        INTERACT_ACROSS_USERS,
17076                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17077                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17078                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17079                            + " requests FLAG_SINGLE_USER, but app does not hold "
17080                            + INTERACT_ACROSS_USERS;
17081                    Slog.w(TAG, msg);
17082                    throw new SecurityException(msg);
17083                }
17084                // Permission passed
17085                result = true;
17086            }
17087        } else if ("system".equals(componentProcessName)) {
17088            result = true;
17089        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17090            // Phone app and persistent apps are allowed to export singleuser providers.
17091            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17092                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17093        }
17094        if (DEBUG_MU) Slog.v(TAG_MU,
17095                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17096                + Integer.toHexString(flags) + ") = " + result);
17097        return result;
17098    }
17099
17100    /**
17101     * Checks to see if the caller is in the same app as the singleton
17102     * component, or the component is in a special app. It allows special apps
17103     * to export singleton components but prevents exporting singleton
17104     * components for regular apps.
17105     */
17106    boolean isValidSingletonCall(int callingUid, int componentUid) {
17107        int componentAppId = UserHandle.getAppId(componentUid);
17108        return UserHandle.isSameApp(callingUid, componentUid)
17109                || componentAppId == Process.SYSTEM_UID
17110                || componentAppId == Process.PHONE_UID
17111                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17112                        == PackageManager.PERMISSION_GRANTED;
17113    }
17114
17115    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17116            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17117            int userId) throws TransactionTooLargeException {
17118        enforceNotIsolatedCaller("bindService");
17119
17120        // Refuse possible leaked file descriptors
17121        if (service != null && service.hasFileDescriptors() == true) {
17122            throw new IllegalArgumentException("File descriptors passed in Intent");
17123        }
17124
17125        if (callingPackage == null) {
17126            throw new IllegalArgumentException("callingPackage cannot be null");
17127        }
17128
17129        synchronized(this) {
17130            return mServices.bindServiceLocked(caller, token, service,
17131                    resolvedType, connection, flags, callingPackage, userId);
17132        }
17133    }
17134
17135    public boolean unbindService(IServiceConnection connection) {
17136        synchronized (this) {
17137            return mServices.unbindServiceLocked(connection);
17138        }
17139    }
17140
17141    public void publishService(IBinder token, Intent intent, IBinder service) {
17142        // Refuse possible leaked file descriptors
17143        if (intent != null && intent.hasFileDescriptors() == true) {
17144            throw new IllegalArgumentException("File descriptors passed in Intent");
17145        }
17146
17147        synchronized(this) {
17148            if (!(token instanceof ServiceRecord)) {
17149                throw new IllegalArgumentException("Invalid service token");
17150            }
17151            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17152        }
17153    }
17154
17155    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17156        // Refuse possible leaked file descriptors
17157        if (intent != null && intent.hasFileDescriptors() == true) {
17158            throw new IllegalArgumentException("File descriptors passed in Intent");
17159        }
17160
17161        synchronized(this) {
17162            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17163        }
17164    }
17165
17166    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17167        synchronized(this) {
17168            if (!(token instanceof ServiceRecord)) {
17169                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17170                throw new IllegalArgumentException("Invalid service token");
17171            }
17172            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17173        }
17174    }
17175
17176    // =========================================================
17177    // BACKUP AND RESTORE
17178    // =========================================================
17179
17180    // Cause the target app to be launched if necessary and its backup agent
17181    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17182    // activity manager to announce its creation.
17183    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17184        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17185        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17186
17187        IPackageManager pm = AppGlobals.getPackageManager();
17188        ApplicationInfo app = null;
17189        try {
17190            app = pm.getApplicationInfo(packageName, 0, userId);
17191        } catch (RemoteException e) {
17192            // can't happen; package manager is process-local
17193        }
17194        if (app == null) {
17195            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17196            return false;
17197        }
17198
17199        synchronized(this) {
17200            // !!! TODO: currently no check here that we're already bound
17201            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17202            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17203            synchronized (stats) {
17204                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17205            }
17206
17207            // Backup agent is now in use, its package can't be stopped.
17208            try {
17209                AppGlobals.getPackageManager().setPackageStoppedState(
17210                        app.packageName, false, UserHandle.getUserId(app.uid));
17211            } catch (RemoteException e) {
17212            } catch (IllegalArgumentException e) {
17213                Slog.w(TAG, "Failed trying to unstop package "
17214                        + app.packageName + ": " + e);
17215            }
17216
17217            BackupRecord r = new BackupRecord(ss, app, backupMode);
17218            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17219                    ? new ComponentName(app.packageName, app.backupAgentName)
17220                    : new ComponentName("android", "FullBackupAgent");
17221            // startProcessLocked() returns existing proc's record if it's already running
17222            ProcessRecord proc = startProcessLocked(app.processName, app,
17223                    false, 0, "backup", hostingName, false, false, false);
17224            if (proc == null) {
17225                Slog.e(TAG, "Unable to start backup agent process " + r);
17226                return false;
17227            }
17228
17229            // If the app is a regular app (uid >= 10000) and not the system server or phone
17230            // process, etc, then mark it as being in full backup so that certain calls to the
17231            // process can be blocked. This is not reset to false anywhere because we kill the
17232            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17233            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17234                proc.inFullBackup = true;
17235            }
17236            r.app = proc;
17237            mBackupTarget = r;
17238            mBackupAppName = app.packageName;
17239
17240            // Try not to kill the process during backup
17241            updateOomAdjLocked(proc);
17242
17243            // If the process is already attached, schedule the creation of the backup agent now.
17244            // If it is not yet live, this will be done when it attaches to the framework.
17245            if (proc.thread != null) {
17246                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17247                try {
17248                    proc.thread.scheduleCreateBackupAgent(app,
17249                            compatibilityInfoForPackageLocked(app), backupMode);
17250                } catch (RemoteException e) {
17251                    // Will time out on the backup manager side
17252                }
17253            } else {
17254                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17255            }
17256            // Invariants: at this point, the target app process exists and the application
17257            // is either already running or in the process of coming up.  mBackupTarget and
17258            // mBackupAppName describe the app, so that when it binds back to the AM we
17259            // know that it's scheduled for a backup-agent operation.
17260        }
17261
17262        return true;
17263    }
17264
17265    @Override
17266    public void clearPendingBackup() {
17267        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17268        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17269
17270        synchronized (this) {
17271            mBackupTarget = null;
17272            mBackupAppName = null;
17273        }
17274    }
17275
17276    // A backup agent has just come up
17277    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17278        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17279                + " = " + agent);
17280
17281        synchronized(this) {
17282            if (!agentPackageName.equals(mBackupAppName)) {
17283                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17284                return;
17285            }
17286        }
17287
17288        long oldIdent = Binder.clearCallingIdentity();
17289        try {
17290            IBackupManager bm = IBackupManager.Stub.asInterface(
17291                    ServiceManager.getService(Context.BACKUP_SERVICE));
17292            bm.agentConnected(agentPackageName, agent);
17293        } catch (RemoteException e) {
17294            // can't happen; the backup manager service is local
17295        } catch (Exception e) {
17296            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17297            e.printStackTrace();
17298        } finally {
17299            Binder.restoreCallingIdentity(oldIdent);
17300        }
17301    }
17302
17303    // done with this agent
17304    public void unbindBackupAgent(ApplicationInfo appInfo) {
17305        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17306        if (appInfo == null) {
17307            Slog.w(TAG, "unbind backup agent for null app");
17308            return;
17309        }
17310
17311        synchronized(this) {
17312            try {
17313                if (mBackupAppName == null) {
17314                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17315                    return;
17316                }
17317
17318                if (!mBackupAppName.equals(appInfo.packageName)) {
17319                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17320                    return;
17321                }
17322
17323                // Not backing this app up any more; reset its OOM adjustment
17324                final ProcessRecord proc = mBackupTarget.app;
17325                updateOomAdjLocked(proc);
17326
17327                // If the app crashed during backup, 'thread' will be null here
17328                if (proc.thread != null) {
17329                    try {
17330                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17331                                compatibilityInfoForPackageLocked(appInfo));
17332                    } catch (Exception e) {
17333                        Slog.e(TAG, "Exception when unbinding backup agent:");
17334                        e.printStackTrace();
17335                    }
17336                }
17337            } finally {
17338                mBackupTarget = null;
17339                mBackupAppName = null;
17340            }
17341        }
17342    }
17343    // =========================================================
17344    // BROADCASTS
17345    // =========================================================
17346
17347    boolean isPendingBroadcastProcessLocked(int pid) {
17348        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17349                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17350    }
17351
17352    void skipPendingBroadcastLocked(int pid) {
17353            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17354            for (BroadcastQueue queue : mBroadcastQueues) {
17355                queue.skipPendingBroadcastLocked(pid);
17356            }
17357    }
17358
17359    // The app just attached; send any pending broadcasts that it should receive
17360    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17361        boolean didSomething = false;
17362        for (BroadcastQueue queue : mBroadcastQueues) {
17363            didSomething |= queue.sendPendingBroadcastsLocked(app);
17364        }
17365        return didSomething;
17366    }
17367
17368    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17369            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17370        enforceNotIsolatedCaller("registerReceiver");
17371        ArrayList<Intent> stickyIntents = null;
17372        ProcessRecord callerApp = null;
17373        int callingUid;
17374        int callingPid;
17375        synchronized(this) {
17376            if (caller != null) {
17377                callerApp = getRecordForAppLocked(caller);
17378                if (callerApp == null) {
17379                    throw new SecurityException(
17380                            "Unable to find app for caller " + caller
17381                            + " (pid=" + Binder.getCallingPid()
17382                            + ") when registering receiver " + receiver);
17383                }
17384                if (callerApp.info.uid != Process.SYSTEM_UID &&
17385                        !callerApp.pkgList.containsKey(callerPackage) &&
17386                        !"android".equals(callerPackage)) {
17387                    throw new SecurityException("Given caller package " + callerPackage
17388                            + " is not running in process " + callerApp);
17389                }
17390                callingUid = callerApp.info.uid;
17391                callingPid = callerApp.pid;
17392            } else {
17393                callerPackage = null;
17394                callingUid = Binder.getCallingUid();
17395                callingPid = Binder.getCallingPid();
17396            }
17397
17398            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17399                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17400
17401            Iterator<String> actions = filter.actionsIterator();
17402            if (actions == null) {
17403                ArrayList<String> noAction = new ArrayList<String>(1);
17404                noAction.add(null);
17405                actions = noAction.iterator();
17406            }
17407
17408            // Collect stickies of users
17409            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17410            while (actions.hasNext()) {
17411                String action = actions.next();
17412                for (int id : userIds) {
17413                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17414                    if (stickies != null) {
17415                        ArrayList<Intent> intents = stickies.get(action);
17416                        if (intents != null) {
17417                            if (stickyIntents == null) {
17418                                stickyIntents = new ArrayList<Intent>();
17419                            }
17420                            stickyIntents.addAll(intents);
17421                        }
17422                    }
17423                }
17424            }
17425        }
17426
17427        ArrayList<Intent> allSticky = null;
17428        if (stickyIntents != null) {
17429            final ContentResolver resolver = mContext.getContentResolver();
17430            // Look for any matching sticky broadcasts...
17431            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17432                Intent intent = stickyIntents.get(i);
17433                // If intent has scheme "content", it will need to acccess
17434                // provider that needs to lock mProviderMap in ActivityThread
17435                // and also it may need to wait application response, so we
17436                // cannot lock ActivityManagerService here.
17437                if (filter.match(resolver, intent, true, TAG) >= 0) {
17438                    if (allSticky == null) {
17439                        allSticky = new ArrayList<Intent>();
17440                    }
17441                    allSticky.add(intent);
17442                }
17443            }
17444        }
17445
17446        // The first sticky in the list is returned directly back to the client.
17447        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17448        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17449        if (receiver == null) {
17450            return sticky;
17451        }
17452
17453        synchronized (this) {
17454            if (callerApp != null && (callerApp.thread == null
17455                    || callerApp.thread.asBinder() != caller.asBinder())) {
17456                // Original caller already died
17457                return null;
17458            }
17459            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17460            if (rl == null) {
17461                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17462                        userId, receiver);
17463                if (rl.app != null) {
17464                    rl.app.receivers.add(rl);
17465                } else {
17466                    try {
17467                        receiver.asBinder().linkToDeath(rl, 0);
17468                    } catch (RemoteException e) {
17469                        return sticky;
17470                    }
17471                    rl.linkedToDeath = true;
17472                }
17473                mRegisteredReceivers.put(receiver.asBinder(), rl);
17474            } else if (rl.uid != callingUid) {
17475                throw new IllegalArgumentException(
17476                        "Receiver requested to register for uid " + callingUid
17477                        + " was previously registered for uid " + rl.uid);
17478            } else if (rl.pid != callingPid) {
17479                throw new IllegalArgumentException(
17480                        "Receiver requested to register for pid " + callingPid
17481                        + " was previously registered for pid " + rl.pid);
17482            } else if (rl.userId != userId) {
17483                throw new IllegalArgumentException(
17484                        "Receiver requested to register for user " + userId
17485                        + " was previously registered for user " + rl.userId);
17486            }
17487            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17488                    permission, callingUid, userId);
17489            rl.add(bf);
17490            if (!bf.debugCheck()) {
17491                Slog.w(TAG, "==> For Dynamic broadcast");
17492            }
17493            mReceiverResolver.addFilter(bf);
17494
17495            // Enqueue broadcasts for all existing stickies that match
17496            // this filter.
17497            if (allSticky != null) {
17498                ArrayList receivers = new ArrayList();
17499                receivers.add(bf);
17500
17501                final int stickyCount = allSticky.size();
17502                for (int i = 0; i < stickyCount; i++) {
17503                    Intent intent = allSticky.get(i);
17504                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17505                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17506                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17507                            null, 0, null, null, false, true, true, -1);
17508                    queue.enqueueParallelBroadcastLocked(r);
17509                    queue.scheduleBroadcastsLocked();
17510                }
17511            }
17512
17513            return sticky;
17514        }
17515    }
17516
17517    public void unregisterReceiver(IIntentReceiver receiver) {
17518        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17519
17520        final long origId = Binder.clearCallingIdentity();
17521        try {
17522            boolean doTrim = false;
17523
17524            synchronized(this) {
17525                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17526                if (rl != null) {
17527                    final BroadcastRecord r = rl.curBroadcast;
17528                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17529                        final boolean doNext = r.queue.finishReceiverLocked(
17530                                r, r.resultCode, r.resultData, r.resultExtras,
17531                                r.resultAbort, false);
17532                        if (doNext) {
17533                            doTrim = true;
17534                            r.queue.processNextBroadcast(false);
17535                        }
17536                    }
17537
17538                    if (rl.app != null) {
17539                        rl.app.receivers.remove(rl);
17540                    }
17541                    removeReceiverLocked(rl);
17542                    if (rl.linkedToDeath) {
17543                        rl.linkedToDeath = false;
17544                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17545                    }
17546                }
17547            }
17548
17549            // If we actually concluded any broadcasts, we might now be able
17550            // to trim the recipients' apps from our working set
17551            if (doTrim) {
17552                trimApplications();
17553                return;
17554            }
17555
17556        } finally {
17557            Binder.restoreCallingIdentity(origId);
17558        }
17559    }
17560
17561    void removeReceiverLocked(ReceiverList rl) {
17562        mRegisteredReceivers.remove(rl.receiver.asBinder());
17563        for (int i = rl.size() - 1; i >= 0; i--) {
17564            mReceiverResolver.removeFilter(rl.get(i));
17565        }
17566    }
17567
17568    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17569        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17570            ProcessRecord r = mLruProcesses.get(i);
17571            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17572                try {
17573                    r.thread.dispatchPackageBroadcast(cmd, packages);
17574                } catch (RemoteException ex) {
17575                }
17576            }
17577        }
17578    }
17579
17580    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17581            int callingUid, int[] users) {
17582        // TODO: come back and remove this assumption to triage all broadcasts
17583        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17584
17585        List<ResolveInfo> receivers = null;
17586        try {
17587            HashSet<ComponentName> singleUserReceivers = null;
17588            boolean scannedFirstReceivers = false;
17589            for (int user : users) {
17590                // Skip users that have Shell restrictions, with exception of always permitted
17591                // Shell broadcasts
17592                if (callingUid == Process.SHELL_UID
17593                        && mUserController.hasUserRestriction(
17594                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17595                        && !isPermittedShellBroadcast(intent)) {
17596                    continue;
17597                }
17598                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17599                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17600                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17601                    // If this is not the system user, we need to check for
17602                    // any receivers that should be filtered out.
17603                    for (int i=0; i<newReceivers.size(); i++) {
17604                        ResolveInfo ri = newReceivers.get(i);
17605                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17606                            newReceivers.remove(i);
17607                            i--;
17608                        }
17609                    }
17610                }
17611                if (newReceivers != null && newReceivers.size() == 0) {
17612                    newReceivers = null;
17613                }
17614                if (receivers == null) {
17615                    receivers = newReceivers;
17616                } else if (newReceivers != null) {
17617                    // We need to concatenate the additional receivers
17618                    // found with what we have do far.  This would be easy,
17619                    // but we also need to de-dup any receivers that are
17620                    // singleUser.
17621                    if (!scannedFirstReceivers) {
17622                        // Collect any single user receivers we had already retrieved.
17623                        scannedFirstReceivers = true;
17624                        for (int i=0; i<receivers.size(); i++) {
17625                            ResolveInfo ri = receivers.get(i);
17626                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17627                                ComponentName cn = new ComponentName(
17628                                        ri.activityInfo.packageName, ri.activityInfo.name);
17629                                if (singleUserReceivers == null) {
17630                                    singleUserReceivers = new HashSet<ComponentName>();
17631                                }
17632                                singleUserReceivers.add(cn);
17633                            }
17634                        }
17635                    }
17636                    // Add the new results to the existing results, tracking
17637                    // and de-dupping single user receivers.
17638                    for (int i=0; i<newReceivers.size(); i++) {
17639                        ResolveInfo ri = newReceivers.get(i);
17640                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17641                            ComponentName cn = new ComponentName(
17642                                    ri.activityInfo.packageName, ri.activityInfo.name);
17643                            if (singleUserReceivers == null) {
17644                                singleUserReceivers = new HashSet<ComponentName>();
17645                            }
17646                            if (!singleUserReceivers.contains(cn)) {
17647                                singleUserReceivers.add(cn);
17648                                receivers.add(ri);
17649                            }
17650                        } else {
17651                            receivers.add(ri);
17652                        }
17653                    }
17654                }
17655            }
17656        } catch (RemoteException ex) {
17657            // pm is in same process, this will never happen.
17658        }
17659        return receivers;
17660    }
17661
17662    private boolean isPermittedShellBroadcast(Intent intent) {
17663        // remote bugreport should always be allowed to be taken
17664        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17665    }
17666
17667    final int broadcastIntentLocked(ProcessRecord callerApp,
17668            String callerPackage, Intent intent, String resolvedType,
17669            IIntentReceiver resultTo, int resultCode, String resultData,
17670            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17671            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17672        intent = new Intent(intent);
17673
17674        // By default broadcasts do not go to stopped apps.
17675        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17676
17677        // If we have not finished booting, don't allow this to launch new processes.
17678        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17679            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17680        }
17681
17682        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17683                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17684                + " ordered=" + ordered + " userid=" + userId);
17685        if ((resultTo != null) && !ordered) {
17686            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17687        }
17688
17689        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17690                ALLOW_NON_FULL, "broadcast", callerPackage);
17691
17692        // Make sure that the user who is receiving this broadcast is running.
17693        // If not, we will just skip it. Make an exception for shutdown broadcasts
17694        // and upgrade steps.
17695
17696        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17697            if ((callingUid != Process.SYSTEM_UID
17698                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17699                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17700                Slog.w(TAG, "Skipping broadcast of " + intent
17701                        + ": user " + userId + " is stopped");
17702                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17703            }
17704        }
17705
17706        BroadcastOptions brOptions = null;
17707        if (bOptions != null) {
17708            brOptions = new BroadcastOptions(bOptions);
17709            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17710                // See if the caller is allowed to do this.  Note we are checking against
17711                // the actual real caller (not whoever provided the operation as say a
17712                // PendingIntent), because that who is actually supplied the arguments.
17713                if (checkComponentPermission(
17714                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17715                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17716                        != PackageManager.PERMISSION_GRANTED) {
17717                    String msg = "Permission Denial: " + intent.getAction()
17718                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17719                            + ", uid=" + callingUid + ")"
17720                            + " requires "
17721                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17722                    Slog.w(TAG, msg);
17723                    throw new SecurityException(msg);
17724                }
17725            }
17726        }
17727
17728        // Verify that protected broadcasts are only being sent by system code,
17729        // and that system code is only sending protected broadcasts.
17730        final String action = intent.getAction();
17731        final boolean isProtectedBroadcast;
17732        try {
17733            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17734        } catch (RemoteException e) {
17735            Slog.w(TAG, "Remote exception", e);
17736            return ActivityManager.BROADCAST_SUCCESS;
17737        }
17738
17739        final boolean isCallerSystem;
17740        switch (UserHandle.getAppId(callingUid)) {
17741            case Process.ROOT_UID:
17742            case Process.SYSTEM_UID:
17743            case Process.PHONE_UID:
17744            case Process.BLUETOOTH_UID:
17745            case Process.NFC_UID:
17746                isCallerSystem = true;
17747                break;
17748            default:
17749                isCallerSystem = (callerApp != null) && callerApp.persistent;
17750                break;
17751        }
17752
17753        if (isCallerSystem) {
17754            if (isProtectedBroadcast
17755                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17756                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17757                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17758                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17759                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17760                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17761                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17762                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17763                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17764                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17765                // Broadcast is either protected, or it's a public action that
17766                // we've relaxed, so it's fine for system internals to send.
17767            } else {
17768                // The vast majority of broadcasts sent from system internals
17769                // should be protected to avoid security holes, so yell loudly
17770                // to ensure we examine these cases.
17771                if (callerApp != null) {
17772                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17773                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17774                            new Throwable());
17775                } else {
17776                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17777                            + " from system uid " + UserHandle.formatUid(callingUid)
17778                            + " pkg " + callerPackage,
17779                            new Throwable());
17780                }
17781            }
17782
17783        } else {
17784            if (isProtectedBroadcast) {
17785                String msg = "Permission Denial: not allowed to send broadcast "
17786                        + action + " from pid="
17787                        + callingPid + ", uid=" + callingUid;
17788                Slog.w(TAG, msg);
17789                throw new SecurityException(msg);
17790
17791            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17792                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17793                // Special case for compatibility: we don't want apps to send this,
17794                // but historically it has not been protected and apps may be using it
17795                // to poke their own app widget.  So, instead of making it protected,
17796                // just limit it to the caller.
17797                if (callerPackage == null) {
17798                    String msg = "Permission Denial: not allowed to send broadcast "
17799                            + action + " from unknown caller.";
17800                    Slog.w(TAG, msg);
17801                    throw new SecurityException(msg);
17802                } else if (intent.getComponent() != null) {
17803                    // They are good enough to send to an explicit component...  verify
17804                    // it is being sent to the calling app.
17805                    if (!intent.getComponent().getPackageName().equals(
17806                            callerPackage)) {
17807                        String msg = "Permission Denial: not allowed to send broadcast "
17808                                + action + " to "
17809                                + intent.getComponent().getPackageName() + " from "
17810                                + callerPackage;
17811                        Slog.w(TAG, msg);
17812                        throw new SecurityException(msg);
17813                    }
17814                } else {
17815                    // Limit broadcast to their own package.
17816                    intent.setPackage(callerPackage);
17817                }
17818            }
17819        }
17820
17821        if (action != null) {
17822            switch (action) {
17823                case Intent.ACTION_UID_REMOVED:
17824                case Intent.ACTION_PACKAGE_REMOVED:
17825                case Intent.ACTION_PACKAGE_CHANGED:
17826                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17827                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17828                case Intent.ACTION_PACKAGES_SUSPENDED:
17829                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17830                    // Handle special intents: if this broadcast is from the package
17831                    // manager about a package being removed, we need to remove all of
17832                    // its activities from the history stack.
17833                    if (checkComponentPermission(
17834                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17835                            callingPid, callingUid, -1, true)
17836                            != PackageManager.PERMISSION_GRANTED) {
17837                        String msg = "Permission Denial: " + intent.getAction()
17838                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17839                                + ", uid=" + callingUid + ")"
17840                                + " requires "
17841                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17842                        Slog.w(TAG, msg);
17843                        throw new SecurityException(msg);
17844                    }
17845                    switch (action) {
17846                        case Intent.ACTION_UID_REMOVED:
17847                            final Bundle intentExtras = intent.getExtras();
17848                            final int uid = intentExtras != null
17849                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17850                            if (uid >= 0) {
17851                                mBatteryStatsService.removeUid(uid);
17852                                mAppOpsService.uidRemoved(uid);
17853                            }
17854                            break;
17855                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17856                            // If resources are unavailable just force stop all those packages
17857                            // and flush the attribute cache as well.
17858                            String list[] =
17859                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17860                            if (list != null && list.length > 0) {
17861                                for (int i = 0; i < list.length; i++) {
17862                                    forceStopPackageLocked(list[i], -1, false, true, true,
17863                                            false, false, userId, "storage unmount");
17864                                }
17865                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17866                                sendPackageBroadcastLocked(
17867                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17868                                        userId);
17869                            }
17870                            break;
17871                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17872                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17873                            break;
17874                        case Intent.ACTION_PACKAGE_REMOVED:
17875                        case Intent.ACTION_PACKAGE_CHANGED:
17876                            Uri data = intent.getData();
17877                            String ssp;
17878                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17879                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17880                                final boolean replacing =
17881                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17882                                final boolean killProcess =
17883                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17884                                final boolean fullUninstall = removed && !replacing;
17885                                if (removed) {
17886                                    if (killProcess) {
17887                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17888                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17889                                                false, true, true, false, fullUninstall, userId,
17890                                                removed ? "pkg removed" : "pkg changed");
17891                                    }
17892                                    final int cmd = killProcess
17893                                            ? IApplicationThread.PACKAGE_REMOVED
17894                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17895                                    sendPackageBroadcastLocked(cmd,
17896                                            new String[] {ssp}, userId);
17897                                    if (fullUninstall) {
17898                                        mAppOpsService.packageRemoved(
17899                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17900
17901                                        // Remove all permissions granted from/to this package
17902                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17903
17904                                        removeTasksByPackageNameLocked(ssp, userId);
17905
17906                                        // Hide the "unsupported display" dialog if necessary.
17907                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17908                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17909                                            mUnsupportedDisplaySizeDialog.dismiss();
17910                                            mUnsupportedDisplaySizeDialog = null;
17911                                        }
17912                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17913                                        mBatteryStatsService.notePackageUninstalled(ssp);
17914                                    }
17915                                } else {
17916                                    if (killProcess) {
17917                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17918                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17919                                                userId, ProcessList.INVALID_ADJ,
17920                                                false, true, true, false, "change " + ssp);
17921                                    }
17922                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17923                                            intent.getStringArrayExtra(
17924                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17925                                }
17926                            }
17927                            break;
17928                        case Intent.ACTION_PACKAGES_SUSPENDED:
17929                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17930                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17931                                    intent.getAction());
17932                            final String[] packageNames = intent.getStringArrayExtra(
17933                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17934                            final int userHandle = intent.getIntExtra(
17935                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17936
17937                            synchronized(ActivityManagerService.this) {
17938                                mRecentTasks.onPackagesSuspendedChanged(
17939                                        packageNames, suspended, userHandle);
17940                            }
17941                            break;
17942                    }
17943                    break;
17944                case Intent.ACTION_PACKAGE_REPLACED:
17945                {
17946                    final Uri data = intent.getData();
17947                    final String ssp;
17948                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17949                        final ApplicationInfo aInfo =
17950                                getPackageManagerInternalLocked().getApplicationInfo(
17951                                        ssp,
17952                                        userId);
17953                        if (aInfo == null) {
17954                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17955                                    + " ssp=" + ssp + " data=" + data);
17956                            return ActivityManager.BROADCAST_SUCCESS;
17957                        }
17958                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17959                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17960                                new String[] {ssp}, userId);
17961                    }
17962                    break;
17963                }
17964                case Intent.ACTION_PACKAGE_ADDED:
17965                {
17966                    // Special case for adding a package: by default turn on compatibility mode.
17967                    Uri data = intent.getData();
17968                    String ssp;
17969                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17970                        final boolean replacing =
17971                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17972                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17973
17974                        try {
17975                            ApplicationInfo ai = AppGlobals.getPackageManager().
17976                                    getApplicationInfo(ssp, 0, 0);
17977                            mBatteryStatsService.notePackageInstalled(ssp,
17978                                    ai != null ? ai.versionCode : 0);
17979                        } catch (RemoteException e) {
17980                        }
17981                    }
17982                    break;
17983                }
17984                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17985                {
17986                    Uri data = intent.getData();
17987                    String ssp;
17988                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17989                        // Hide the "unsupported display" dialog if necessary.
17990                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17991                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17992                            mUnsupportedDisplaySizeDialog.dismiss();
17993                            mUnsupportedDisplaySizeDialog = null;
17994                        }
17995                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17996                    }
17997                    break;
17998                }
17999                case Intent.ACTION_TIMEZONE_CHANGED:
18000                    // If this is the time zone changed action, queue up a message that will reset
18001                    // the timezone of all currently running processes. This message will get
18002                    // queued up before the broadcast happens.
18003                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18004                    break;
18005                case Intent.ACTION_TIME_CHANGED:
18006                    // If the user set the time, let all running processes know.
18007                    final int is24Hour =
18008                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18009                                    : 0;
18010                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18011                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18012                    synchronized (stats) {
18013                        stats.noteCurrentTimeChangedLocked();
18014                    }
18015                    break;
18016                case Intent.ACTION_CLEAR_DNS_CACHE:
18017                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18018                    break;
18019                case Proxy.PROXY_CHANGE_ACTION:
18020                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18021                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18022                    break;
18023                case android.hardware.Camera.ACTION_NEW_PICTURE:
18024                case android.hardware.Camera.ACTION_NEW_VIDEO:
18025                    // These broadcasts are no longer allowed by the system, since they can
18026                    // cause significant thrashing at a crictical point (using the camera).
18027                    // Apps should use JobScehduler to monitor for media provider changes.
18028                    Slog.w(TAG, action + " no longer allowed; dropping from "
18029                            + UserHandle.formatUid(callingUid));
18030                    if (resultTo != null) {
18031                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18032                        try {
18033                            queue.performReceiveLocked(callerApp, resultTo, intent,
18034                                    Activity.RESULT_CANCELED, null, null,
18035                                    false, false, userId);
18036                        } catch (RemoteException e) {
18037                            Slog.w(TAG, "Failure ["
18038                                    + queue.mQueueName + "] sending broadcast result of "
18039                                    + intent, e);
18040
18041                        }
18042                    }
18043                    // Lie; we don't want to crash the app.
18044                    return ActivityManager.BROADCAST_SUCCESS;
18045            }
18046        }
18047
18048        // Add to the sticky list if requested.
18049        if (sticky) {
18050            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18051                    callingPid, callingUid)
18052                    != PackageManager.PERMISSION_GRANTED) {
18053                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18054                        + callingPid + ", uid=" + callingUid
18055                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18056                Slog.w(TAG, msg);
18057                throw new SecurityException(msg);
18058            }
18059            if (requiredPermissions != null && requiredPermissions.length > 0) {
18060                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18061                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18062                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18063            }
18064            if (intent.getComponent() != null) {
18065                throw new SecurityException(
18066                        "Sticky broadcasts can't target a specific component");
18067            }
18068            // We use userId directly here, since the "all" target is maintained
18069            // as a separate set of sticky broadcasts.
18070            if (userId != UserHandle.USER_ALL) {
18071                // But first, if this is not a broadcast to all users, then
18072                // make sure it doesn't conflict with an existing broadcast to
18073                // all users.
18074                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18075                        UserHandle.USER_ALL);
18076                if (stickies != null) {
18077                    ArrayList<Intent> list = stickies.get(intent.getAction());
18078                    if (list != null) {
18079                        int N = list.size();
18080                        int i;
18081                        for (i=0; i<N; i++) {
18082                            if (intent.filterEquals(list.get(i))) {
18083                                throw new IllegalArgumentException(
18084                                        "Sticky broadcast " + intent + " for user "
18085                                        + userId + " conflicts with existing global broadcast");
18086                            }
18087                        }
18088                    }
18089                }
18090            }
18091            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18092            if (stickies == null) {
18093                stickies = new ArrayMap<>();
18094                mStickyBroadcasts.put(userId, stickies);
18095            }
18096            ArrayList<Intent> list = stickies.get(intent.getAction());
18097            if (list == null) {
18098                list = new ArrayList<>();
18099                stickies.put(intent.getAction(), list);
18100            }
18101            final int stickiesCount = list.size();
18102            int i;
18103            for (i = 0; i < stickiesCount; i++) {
18104                if (intent.filterEquals(list.get(i))) {
18105                    // This sticky already exists, replace it.
18106                    list.set(i, new Intent(intent));
18107                    break;
18108                }
18109            }
18110            if (i >= stickiesCount) {
18111                list.add(new Intent(intent));
18112            }
18113        }
18114
18115        int[] users;
18116        if (userId == UserHandle.USER_ALL) {
18117            // Caller wants broadcast to go to all started users.
18118            users = mUserController.getStartedUserArrayLocked();
18119        } else {
18120            // Caller wants broadcast to go to one specific user.
18121            users = new int[] {userId};
18122        }
18123
18124        // Figure out who all will receive this broadcast.
18125        List receivers = null;
18126        List<BroadcastFilter> registeredReceivers = null;
18127        // Need to resolve the intent to interested receivers...
18128        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18129                 == 0) {
18130            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18131        }
18132        if (intent.getComponent() == null) {
18133            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18134                // Query one target user at a time, excluding shell-restricted users
18135                for (int i = 0; i < users.length; i++) {
18136                    if (mUserController.hasUserRestriction(
18137                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18138                        continue;
18139                    }
18140                    List<BroadcastFilter> registeredReceiversForUser =
18141                            mReceiverResolver.queryIntent(intent,
18142                                    resolvedType, false, users[i]);
18143                    if (registeredReceivers == null) {
18144                        registeredReceivers = registeredReceiversForUser;
18145                    } else if (registeredReceiversForUser != null) {
18146                        registeredReceivers.addAll(registeredReceiversForUser);
18147                    }
18148                }
18149            } else {
18150                registeredReceivers = mReceiverResolver.queryIntent(intent,
18151                        resolvedType, false, userId);
18152            }
18153        }
18154
18155        final boolean replacePending =
18156                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18157
18158        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18159                + " replacePending=" + replacePending);
18160
18161        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18162        if (!ordered && NR > 0) {
18163            // If we are not serializing this broadcast, then send the
18164            // registered receivers separately so they don't wait for the
18165            // components to be launched.
18166            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18167            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18168                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18169                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18170                    resultExtras, ordered, sticky, false, userId);
18171            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18172            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18173            if (!replaced) {
18174                queue.enqueueParallelBroadcastLocked(r);
18175                queue.scheduleBroadcastsLocked();
18176            }
18177            registeredReceivers = null;
18178            NR = 0;
18179        }
18180
18181        // Merge into one list.
18182        int ir = 0;
18183        if (receivers != null) {
18184            // A special case for PACKAGE_ADDED: do not allow the package
18185            // being added to see this broadcast.  This prevents them from
18186            // using this as a back door to get run as soon as they are
18187            // installed.  Maybe in the future we want to have a special install
18188            // broadcast or such for apps, but we'd like to deliberately make
18189            // this decision.
18190            String skipPackages[] = null;
18191            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18192                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18193                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18194                Uri data = intent.getData();
18195                if (data != null) {
18196                    String pkgName = data.getSchemeSpecificPart();
18197                    if (pkgName != null) {
18198                        skipPackages = new String[] { pkgName };
18199                    }
18200                }
18201            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18202                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18203            }
18204            if (skipPackages != null && (skipPackages.length > 0)) {
18205                for (String skipPackage : skipPackages) {
18206                    if (skipPackage != null) {
18207                        int NT = receivers.size();
18208                        for (int it=0; it<NT; it++) {
18209                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18210                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18211                                receivers.remove(it);
18212                                it--;
18213                                NT--;
18214                            }
18215                        }
18216                    }
18217                }
18218            }
18219
18220            int NT = receivers != null ? receivers.size() : 0;
18221            int it = 0;
18222            ResolveInfo curt = null;
18223            BroadcastFilter curr = null;
18224            while (it < NT && ir < NR) {
18225                if (curt == null) {
18226                    curt = (ResolveInfo)receivers.get(it);
18227                }
18228                if (curr == null) {
18229                    curr = registeredReceivers.get(ir);
18230                }
18231                if (curr.getPriority() >= curt.priority) {
18232                    // Insert this broadcast record into the final list.
18233                    receivers.add(it, curr);
18234                    ir++;
18235                    curr = null;
18236                    it++;
18237                    NT++;
18238                } else {
18239                    // Skip to the next ResolveInfo in the final list.
18240                    it++;
18241                    curt = null;
18242                }
18243            }
18244        }
18245        while (ir < NR) {
18246            if (receivers == null) {
18247                receivers = new ArrayList();
18248            }
18249            receivers.add(registeredReceivers.get(ir));
18250            ir++;
18251        }
18252
18253        if ((receivers != null && receivers.size() > 0)
18254                || resultTo != null) {
18255            BroadcastQueue queue = broadcastQueueForIntent(intent);
18256            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18257                    callerPackage, callingPid, callingUid, resolvedType,
18258                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18259                    resultData, resultExtras, ordered, sticky, false, userId);
18260
18261            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18262                    + ": prev had " + queue.mOrderedBroadcasts.size());
18263            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18264                    "Enqueueing broadcast " + r.intent.getAction());
18265
18266            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18267            if (!replaced) {
18268                queue.enqueueOrderedBroadcastLocked(r);
18269                queue.scheduleBroadcastsLocked();
18270            }
18271        } else {
18272            // There was nobody interested in the broadcast, but we still want to record
18273            // that it happened.
18274            if (intent.getComponent() == null && intent.getPackage() == null
18275                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18276                // This was an implicit broadcast... let's record it for posterity.
18277                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18278            }
18279        }
18280
18281        return ActivityManager.BROADCAST_SUCCESS;
18282    }
18283
18284    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18285            int skipCount, long dispatchTime) {
18286        final long now = SystemClock.elapsedRealtime();
18287        if (mCurBroadcastStats == null ||
18288                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18289            mLastBroadcastStats = mCurBroadcastStats;
18290            if (mLastBroadcastStats != null) {
18291                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18292                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18293            }
18294            mCurBroadcastStats = new BroadcastStats();
18295        }
18296        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18297    }
18298
18299    final Intent verifyBroadcastLocked(Intent intent) {
18300        // Refuse possible leaked file descriptors
18301        if (intent != null && intent.hasFileDescriptors() == true) {
18302            throw new IllegalArgumentException("File descriptors passed in Intent");
18303        }
18304
18305        int flags = intent.getFlags();
18306
18307        if (!mProcessesReady) {
18308            // if the caller really truly claims to know what they're doing, go
18309            // ahead and allow the broadcast without launching any receivers
18310            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18311                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18312            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18313                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18314                        + " before boot completion");
18315                throw new IllegalStateException("Cannot broadcast before boot completed");
18316            }
18317        }
18318
18319        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18320            throw new IllegalArgumentException(
18321                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18322        }
18323
18324        return intent;
18325    }
18326
18327    public final int broadcastIntent(IApplicationThread caller,
18328            Intent intent, String resolvedType, IIntentReceiver resultTo,
18329            int resultCode, String resultData, Bundle resultExtras,
18330            String[] requiredPermissions, int appOp, Bundle bOptions,
18331            boolean serialized, boolean sticky, int userId) {
18332        enforceNotIsolatedCaller("broadcastIntent");
18333        synchronized(this) {
18334            intent = verifyBroadcastLocked(intent);
18335
18336            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18337            final int callingPid = Binder.getCallingPid();
18338            final int callingUid = Binder.getCallingUid();
18339            final long origId = Binder.clearCallingIdentity();
18340            int res = broadcastIntentLocked(callerApp,
18341                    callerApp != null ? callerApp.info.packageName : null,
18342                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18343                    requiredPermissions, appOp, bOptions, serialized, sticky,
18344                    callingPid, callingUid, userId);
18345            Binder.restoreCallingIdentity(origId);
18346            return res;
18347        }
18348    }
18349
18350
18351    int broadcastIntentInPackage(String packageName, int uid,
18352            Intent intent, String resolvedType, IIntentReceiver resultTo,
18353            int resultCode, String resultData, Bundle resultExtras,
18354            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18355            int userId) {
18356        synchronized(this) {
18357            intent = verifyBroadcastLocked(intent);
18358
18359            final long origId = Binder.clearCallingIdentity();
18360            String[] requiredPermissions = requiredPermission == null ? null
18361                    : new String[] {requiredPermission};
18362            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18363                    resultTo, resultCode, resultData, resultExtras,
18364                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18365                    sticky, -1, uid, userId);
18366            Binder.restoreCallingIdentity(origId);
18367            return res;
18368        }
18369    }
18370
18371    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18372        // Refuse possible leaked file descriptors
18373        if (intent != null && intent.hasFileDescriptors() == true) {
18374            throw new IllegalArgumentException("File descriptors passed in Intent");
18375        }
18376
18377        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18378                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18379
18380        synchronized(this) {
18381            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18382                    != PackageManager.PERMISSION_GRANTED) {
18383                String msg = "Permission Denial: unbroadcastIntent() from pid="
18384                        + Binder.getCallingPid()
18385                        + ", uid=" + Binder.getCallingUid()
18386                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18387                Slog.w(TAG, msg);
18388                throw new SecurityException(msg);
18389            }
18390            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18391            if (stickies != null) {
18392                ArrayList<Intent> list = stickies.get(intent.getAction());
18393                if (list != null) {
18394                    int N = list.size();
18395                    int i;
18396                    for (i=0; i<N; i++) {
18397                        if (intent.filterEquals(list.get(i))) {
18398                            list.remove(i);
18399                            break;
18400                        }
18401                    }
18402                    if (list.size() <= 0) {
18403                        stickies.remove(intent.getAction());
18404                    }
18405                }
18406                if (stickies.size() <= 0) {
18407                    mStickyBroadcasts.remove(userId);
18408                }
18409            }
18410        }
18411    }
18412
18413    void backgroundServicesFinishedLocked(int userId) {
18414        for (BroadcastQueue queue : mBroadcastQueues) {
18415            queue.backgroundServicesFinishedLocked(userId);
18416        }
18417    }
18418
18419    public void finishReceiver(IBinder who, int resultCode, String resultData,
18420            Bundle resultExtras, boolean resultAbort, int flags) {
18421        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18422
18423        // Refuse possible leaked file descriptors
18424        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18425            throw new IllegalArgumentException("File descriptors passed in Bundle");
18426        }
18427
18428        final long origId = Binder.clearCallingIdentity();
18429        try {
18430            boolean doNext = false;
18431            BroadcastRecord r;
18432
18433            synchronized(this) {
18434                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18435                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18436                r = queue.getMatchingOrderedReceiver(who);
18437                if (r != null) {
18438                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18439                        resultData, resultExtras, resultAbort, true);
18440                }
18441            }
18442
18443            if (doNext) {
18444                r.queue.processNextBroadcast(false);
18445            }
18446            trimApplications();
18447        } finally {
18448            Binder.restoreCallingIdentity(origId);
18449        }
18450    }
18451
18452    // =========================================================
18453    // INSTRUMENTATION
18454    // =========================================================
18455
18456    public boolean startInstrumentation(ComponentName className,
18457            String profileFile, int flags, Bundle arguments,
18458            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18459            int userId, String abiOverride) {
18460        enforceNotIsolatedCaller("startInstrumentation");
18461        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18462                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18463        // Refuse possible leaked file descriptors
18464        if (arguments != null && arguments.hasFileDescriptors()) {
18465            throw new IllegalArgumentException("File descriptors passed in Bundle");
18466        }
18467
18468        synchronized(this) {
18469            InstrumentationInfo ii = null;
18470            ApplicationInfo ai = null;
18471            try {
18472                ii = mContext.getPackageManager().getInstrumentationInfo(
18473                    className, STOCK_PM_FLAGS);
18474                ai = AppGlobals.getPackageManager().getApplicationInfo(
18475                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18476            } catch (PackageManager.NameNotFoundException e) {
18477            } catch (RemoteException e) {
18478            }
18479            if (ii == null) {
18480                reportStartInstrumentationFailureLocked(watcher, className,
18481                        "Unable to find instrumentation info for: " + className);
18482                return false;
18483            }
18484            if (ai == null) {
18485                reportStartInstrumentationFailureLocked(watcher, className,
18486                        "Unable to find instrumentation target package: " + ii.targetPackage);
18487                return false;
18488            }
18489            if (!ai.hasCode()) {
18490                reportStartInstrumentationFailureLocked(watcher, className,
18491                        "Instrumentation target has no code: " + ii.targetPackage);
18492                return false;
18493            }
18494
18495            int match = mContext.getPackageManager().checkSignatures(
18496                    ii.targetPackage, ii.packageName);
18497            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18498                String msg = "Permission Denial: starting instrumentation "
18499                        + className + " from pid="
18500                        + Binder.getCallingPid()
18501                        + ", uid=" + Binder.getCallingPid()
18502                        + " not allowed because package " + ii.packageName
18503                        + " does not have a signature matching the target "
18504                        + ii.targetPackage;
18505                reportStartInstrumentationFailureLocked(watcher, className, msg);
18506                throw new SecurityException(msg);
18507            }
18508
18509            final long origId = Binder.clearCallingIdentity();
18510            // Instrumentation can kill and relaunch even persistent processes
18511            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18512                    "start instr");
18513            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18514            app.instrumentationClass = className;
18515            app.instrumentationInfo = ai;
18516            app.instrumentationProfileFile = profileFile;
18517            app.instrumentationArguments = arguments;
18518            app.instrumentationWatcher = watcher;
18519            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18520            app.instrumentationResultClass = className;
18521            Binder.restoreCallingIdentity(origId);
18522        }
18523
18524        return true;
18525    }
18526
18527    /**
18528     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18529     * error to the logs, but if somebody is watching, send the report there too.  This enables
18530     * the "am" command to report errors with more information.
18531     *
18532     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18533     * @param cn The component name of the instrumentation.
18534     * @param report The error report.
18535     */
18536    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18537            ComponentName cn, String report) {
18538        Slog.w(TAG, report);
18539        if (watcher != null) {
18540            Bundle results = new Bundle();
18541            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18542            results.putString("Error", report);
18543            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18544        }
18545    }
18546
18547    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18548        if (app.instrumentationWatcher != null) {
18549            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18550                    app.instrumentationClass, resultCode, results);
18551        }
18552
18553        // Can't call out of the system process with a lock held, so post a message.
18554        if (app.instrumentationUiAutomationConnection != null) {
18555            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18556                    app.instrumentationUiAutomationConnection).sendToTarget();
18557        }
18558
18559        app.instrumentationWatcher = null;
18560        app.instrumentationUiAutomationConnection = null;
18561        app.instrumentationClass = null;
18562        app.instrumentationInfo = null;
18563        app.instrumentationProfileFile = null;
18564        app.instrumentationArguments = null;
18565
18566        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18567                "finished inst");
18568    }
18569
18570    public void finishInstrumentation(IApplicationThread target,
18571            int resultCode, Bundle results) {
18572        int userId = UserHandle.getCallingUserId();
18573        // Refuse possible leaked file descriptors
18574        if (results != null && results.hasFileDescriptors()) {
18575            throw new IllegalArgumentException("File descriptors passed in Intent");
18576        }
18577
18578        synchronized(this) {
18579            ProcessRecord app = getRecordForAppLocked(target);
18580            if (app == null) {
18581                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18582                return;
18583            }
18584            final long origId = Binder.clearCallingIdentity();
18585            finishInstrumentationLocked(app, resultCode, results);
18586            Binder.restoreCallingIdentity(origId);
18587        }
18588    }
18589
18590    // =========================================================
18591    // CONFIGURATION
18592    // =========================================================
18593
18594    public ConfigurationInfo getDeviceConfigurationInfo() {
18595        ConfigurationInfo config = new ConfigurationInfo();
18596        synchronized (this) {
18597            config.reqTouchScreen = mConfiguration.touchscreen;
18598            config.reqKeyboardType = mConfiguration.keyboard;
18599            config.reqNavigation = mConfiguration.navigation;
18600            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18601                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18602                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18603            }
18604            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18605                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18606                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18607            }
18608            config.reqGlEsVersion = GL_ES_VERSION;
18609        }
18610        return config;
18611    }
18612
18613    ActivityStack getFocusedStack() {
18614        return mStackSupervisor.getFocusedStack();
18615    }
18616
18617    @Override
18618    public int getFocusedStackId() throws RemoteException {
18619        ActivityStack focusedStack = getFocusedStack();
18620        if (focusedStack != null) {
18621            return focusedStack.getStackId();
18622        }
18623        return -1;
18624    }
18625
18626    public Configuration getConfiguration() {
18627        Configuration ci;
18628        synchronized(this) {
18629            ci = new Configuration(mConfiguration);
18630            ci.userSetLocale = false;
18631        }
18632        return ci;
18633    }
18634
18635    @Override
18636    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18637        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18638        synchronized (this) {
18639            mSuppressResizeConfigChanges = suppress;
18640        }
18641    }
18642
18643    @Override
18644    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18645        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18646        if (fromStackId == HOME_STACK_ID) {
18647            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18648        }
18649        synchronized (this) {
18650            final long origId = Binder.clearCallingIdentity();
18651            try {
18652                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18653            } finally {
18654                Binder.restoreCallingIdentity(origId);
18655            }
18656        }
18657    }
18658
18659    @Override
18660    public void updatePersistentConfiguration(Configuration values) {
18661        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18662                "updateConfiguration()");
18663        enforceWriteSettingsPermission("updateConfiguration()");
18664        if (values == null) {
18665            throw new NullPointerException("Configuration must not be null");
18666        }
18667
18668        int userId = UserHandle.getCallingUserId();
18669
18670        synchronized(this) {
18671            final long origId = Binder.clearCallingIdentity();
18672            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18673            Binder.restoreCallingIdentity(origId);
18674        }
18675    }
18676
18677    private void updateFontScaleIfNeeded() {
18678        final int currentUserId;
18679        synchronized(this) {
18680            currentUserId = mUserController.getCurrentUserIdLocked();
18681        }
18682        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18683                FONT_SCALE, 1.0f, currentUserId);
18684        if (mConfiguration.fontScale != scaleFactor) {
18685            final Configuration configuration = mWindowManager.computeNewConfiguration();
18686            configuration.fontScale = scaleFactor;
18687            updatePersistentConfiguration(configuration);
18688        }
18689    }
18690
18691    private void enforceWriteSettingsPermission(String func) {
18692        int uid = Binder.getCallingUid();
18693        if (uid == Process.ROOT_UID) {
18694            return;
18695        }
18696
18697        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18698                Settings.getPackageNameForUid(mContext, uid), false)) {
18699            return;
18700        }
18701
18702        String msg = "Permission Denial: " + func + " from pid="
18703                + Binder.getCallingPid()
18704                + ", uid=" + uid
18705                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18706        Slog.w(TAG, msg);
18707        throw new SecurityException(msg);
18708    }
18709
18710    public void updateConfiguration(Configuration values) {
18711        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18712                "updateConfiguration()");
18713
18714        synchronized(this) {
18715            if (values == null && mWindowManager != null) {
18716                // sentinel: fetch the current configuration from the window manager
18717                values = mWindowManager.computeNewConfiguration();
18718            }
18719
18720            if (mWindowManager != null) {
18721                mProcessList.applyDisplaySize(mWindowManager);
18722            }
18723
18724            final long origId = Binder.clearCallingIdentity();
18725            if (values != null) {
18726                Settings.System.clearConfiguration(values);
18727            }
18728            updateConfigurationLocked(values, null, false);
18729            Binder.restoreCallingIdentity(origId);
18730        }
18731    }
18732
18733    void updateUserConfigurationLocked() {
18734        Configuration configuration = new Configuration(mConfiguration);
18735        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18736                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18737        updateConfigurationLocked(configuration, null, false);
18738    }
18739
18740    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18741            boolean initLocale) {
18742        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18743    }
18744
18745    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18746            boolean initLocale, boolean deferResume) {
18747        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18748        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18749                UserHandle.USER_NULL, deferResume);
18750    }
18751
18752    // To cache the list of supported system locales
18753    private String[] mSupportedSystemLocales = null;
18754
18755    /**
18756     * Do either or both things: (1) change the current configuration, and (2)
18757     * make sure the given activity is running with the (now) current
18758     * configuration.  Returns true if the activity has been left running, or
18759     * false if <var>starting</var> is being destroyed to match the new
18760     * configuration.
18761     *
18762     * @param userId is only used when persistent parameter is set to true to persist configuration
18763     *               for that particular user
18764     */
18765    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18766            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18767        int changes = 0;
18768
18769        if (mWindowManager != null) {
18770            mWindowManager.deferSurfaceLayout();
18771        }
18772        if (values != null) {
18773            Configuration newConfig = new Configuration(mConfiguration);
18774            changes = newConfig.updateFrom(values);
18775            if (changes != 0) {
18776                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18777                        "Updating configuration to: " + values);
18778
18779                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18780
18781                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18782                    final LocaleList locales = values.getLocales();
18783                    int bestLocaleIndex = 0;
18784                    if (locales.size() > 1) {
18785                        if (mSupportedSystemLocales == null) {
18786                            mSupportedSystemLocales =
18787                                    Resources.getSystem().getAssets().getLocales();
18788                        }
18789                        bestLocaleIndex = Math.max(0,
18790                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18791                    }
18792                    SystemProperties.set("persist.sys.locale",
18793                            locales.get(bestLocaleIndex).toLanguageTag());
18794                    LocaleList.setDefault(locales, bestLocaleIndex);
18795                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18796                            locales.get(bestLocaleIndex)));
18797                }
18798
18799                mConfigurationSeq++;
18800                if (mConfigurationSeq <= 0) {
18801                    mConfigurationSeq = 1;
18802                }
18803                newConfig.seq = mConfigurationSeq;
18804                mConfiguration = newConfig;
18805                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18806                mUsageStatsService.reportConfigurationChange(newConfig,
18807                        mUserController.getCurrentUserIdLocked());
18808                //mUsageStatsService.noteStartConfig(newConfig);
18809
18810                final Configuration configCopy = new Configuration(mConfiguration);
18811
18812                // TODO: If our config changes, should we auto dismiss any currently
18813                // showing dialogs?
18814                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18815
18816                AttributeCache ac = AttributeCache.instance();
18817                if (ac != null) {
18818                    ac.updateConfiguration(configCopy);
18819                }
18820
18821                // Make sure all resources in our process are updated
18822                // right now, so that anyone who is going to retrieve
18823                // resource values after we return will be sure to get
18824                // the new ones.  This is especially important during
18825                // boot, where the first config change needs to guarantee
18826                // all resources have that config before following boot
18827                // code is executed.
18828                mSystemThread.applyConfigurationToResources(configCopy);
18829
18830                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18831                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18832                    msg.obj = new Configuration(configCopy);
18833                    msg.arg1 = userId;
18834                    mHandler.sendMessage(msg);
18835                }
18836
18837                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18838                if (isDensityChange) {
18839                    // Reset the unsupported display size dialog.
18840                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18841
18842                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18843                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18844                }
18845
18846                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18847                    ProcessRecord app = mLruProcesses.get(i);
18848                    try {
18849                        if (app.thread != null) {
18850                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18851                                    + app.processName + " new config " + mConfiguration);
18852                            app.thread.scheduleConfigurationChanged(configCopy);
18853                        }
18854                    } catch (Exception e) {
18855                    }
18856                }
18857                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18858                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18859                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18860                        | Intent.FLAG_RECEIVER_FOREGROUND);
18861                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18862                        null, AppOpsManager.OP_NONE, null, false, false,
18863                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18864                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18865                    // Tell the shortcut manager that the system locale changed.  It needs to know
18866                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18867                    // we "push" from here, rather than having the service listen to the broadcast.
18868                    final ShortcutServiceInternal shortcutService =
18869                            LocalServices.getService(ShortcutServiceInternal.class);
18870                    if (shortcutService != null) {
18871                        shortcutService.onSystemLocaleChangedNoLock();
18872                    }
18873
18874                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18875                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18876                    if (!mProcessesReady) {
18877                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18878                    }
18879                    broadcastIntentLocked(null, null, intent,
18880                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18881                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18882                }
18883            }
18884            // Update the configuration with WM first and check if any of the stacks need to be
18885            // resized due to the configuration change. If so, resize the stacks now and do any
18886            // relaunches if necessary. This way we don't need to relaunch again below in
18887            // ensureActivityConfigurationLocked().
18888            if (mWindowManager != null) {
18889                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18890                if (resizedStacks != null) {
18891                    for (int stackId : resizedStacks) {
18892                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18893                        mStackSupervisor.resizeStackLocked(
18894                                stackId, newBounds, null, null, false, false, deferResume);
18895                    }
18896                }
18897            }
18898        }
18899
18900        boolean kept = true;
18901        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18902        // mainStack is null during startup.
18903        if (mainStack != null) {
18904            if (changes != 0 && starting == null) {
18905                // If the configuration changed, and the caller is not already
18906                // in the process of starting an activity, then find the top
18907                // activity to check if its configuration needs to change.
18908                starting = mainStack.topRunningActivityLocked();
18909            }
18910
18911            if (starting != null) {
18912                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18913                // And we need to make sure at this point that all other activities
18914                // are made visible with the correct configuration.
18915                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18916                        !PRESERVE_WINDOWS);
18917            }
18918        }
18919        if (mWindowManager != null) {
18920            mWindowManager.continueSurfaceLayout();
18921        }
18922        return kept;
18923    }
18924
18925    /**
18926     * Decide based on the configuration whether we should shouw the ANR,
18927     * crash, etc dialogs.  The idea is that if there is no affordence to
18928     * press the on-screen buttons, or the user experience would be more
18929     * greatly impacted than the crash itself, we shouldn't show the dialog.
18930     *
18931     * A thought: SystemUI might also want to get told about this, the Power
18932     * dialog / global actions also might want different behaviors.
18933     */
18934    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18935        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18936                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18937                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18938        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18939        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18940                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18941        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18942    }
18943
18944    @Override
18945    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18946        synchronized (this) {
18947            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18948            if (srec != null) {
18949                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18950            }
18951        }
18952        return false;
18953    }
18954
18955    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18956            Intent resultData) {
18957
18958        synchronized (this) {
18959            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18960            if (r != null) {
18961                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18962            }
18963            return false;
18964        }
18965    }
18966
18967    public int getLaunchedFromUid(IBinder activityToken) {
18968        ActivityRecord srec;
18969        synchronized (this) {
18970            srec = ActivityRecord.forTokenLocked(activityToken);
18971        }
18972        if (srec == null) {
18973            return -1;
18974        }
18975        return srec.launchedFromUid;
18976    }
18977
18978    public String getLaunchedFromPackage(IBinder activityToken) {
18979        ActivityRecord srec;
18980        synchronized (this) {
18981            srec = ActivityRecord.forTokenLocked(activityToken);
18982        }
18983        if (srec == null) {
18984            return null;
18985        }
18986        return srec.launchedFromPackage;
18987    }
18988
18989    // =========================================================
18990    // LIFETIME MANAGEMENT
18991    // =========================================================
18992
18993    // Returns which broadcast queue the app is the current [or imminent] receiver
18994    // on, or 'null' if the app is not an active broadcast recipient.
18995    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18996        BroadcastRecord r = app.curReceiver;
18997        if (r != null) {
18998            return r.queue;
18999        }
19000
19001        // It's not the current receiver, but it might be starting up to become one
19002        synchronized (this) {
19003            for (BroadcastQueue queue : mBroadcastQueues) {
19004                r = queue.mPendingBroadcast;
19005                if (r != null && r.curApp == app) {
19006                    // found it; report which queue it's in
19007                    return queue;
19008                }
19009            }
19010        }
19011
19012        return null;
19013    }
19014
19015    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19016            int targetUid, ComponentName targetComponent, String targetProcess) {
19017        if (!mTrackingAssociations) {
19018            return null;
19019        }
19020        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19021                = mAssociations.get(targetUid);
19022        if (components == null) {
19023            components = new ArrayMap<>();
19024            mAssociations.put(targetUid, components);
19025        }
19026        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19027        if (sourceUids == null) {
19028            sourceUids = new SparseArray<>();
19029            components.put(targetComponent, sourceUids);
19030        }
19031        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19032        if (sourceProcesses == null) {
19033            sourceProcesses = new ArrayMap<>();
19034            sourceUids.put(sourceUid, sourceProcesses);
19035        }
19036        Association ass = sourceProcesses.get(sourceProcess);
19037        if (ass == null) {
19038            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19039                    targetProcess);
19040            sourceProcesses.put(sourceProcess, ass);
19041        }
19042        ass.mCount++;
19043        ass.mNesting++;
19044        if (ass.mNesting == 1) {
19045            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19046            ass.mLastState = sourceState;
19047        }
19048        return ass;
19049    }
19050
19051    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19052            ComponentName targetComponent) {
19053        if (!mTrackingAssociations) {
19054            return;
19055        }
19056        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19057                = mAssociations.get(targetUid);
19058        if (components == null) {
19059            return;
19060        }
19061        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19062        if (sourceUids == null) {
19063            return;
19064        }
19065        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19066        if (sourceProcesses == null) {
19067            return;
19068        }
19069        Association ass = sourceProcesses.get(sourceProcess);
19070        if (ass == null || ass.mNesting <= 0) {
19071            return;
19072        }
19073        ass.mNesting--;
19074        if (ass.mNesting == 0) {
19075            long uptime = SystemClock.uptimeMillis();
19076            ass.mTime += uptime - ass.mStartTime;
19077            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19078                    += uptime - ass.mLastStateUptime;
19079            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19080        }
19081    }
19082
19083    private void noteUidProcessState(final int uid, final int state) {
19084        mBatteryStatsService.noteUidProcessState(uid, state);
19085        if (mTrackingAssociations) {
19086            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19087                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19088                        = mAssociations.valueAt(i1);
19089                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19090                    SparseArray<ArrayMap<String, Association>> sourceUids
19091                            = targetComponents.valueAt(i2);
19092                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19093                    if (sourceProcesses != null) {
19094                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19095                            Association ass = sourceProcesses.valueAt(i4);
19096                            if (ass.mNesting >= 1) {
19097                                // currently associated
19098                                long uptime = SystemClock.uptimeMillis();
19099                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19100                                        += uptime - ass.mLastStateUptime;
19101                                ass.mLastState = state;
19102                                ass.mLastStateUptime = uptime;
19103                            }
19104                        }
19105                    }
19106                }
19107            }
19108        }
19109    }
19110
19111    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19112            boolean doingAll, long now) {
19113        if (mAdjSeq == app.adjSeq) {
19114            // This adjustment has already been computed.
19115            return app.curRawAdj;
19116        }
19117
19118        if (app.thread == null) {
19119            app.adjSeq = mAdjSeq;
19120            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19121            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19122            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19123        }
19124
19125        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19126        app.adjSource = null;
19127        app.adjTarget = null;
19128        app.empty = false;
19129        app.cached = false;
19130
19131        final int activitiesSize = app.activities.size();
19132
19133        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19134            // The max adjustment doesn't allow this app to be anything
19135            // below foreground, so it is not worth doing work for it.
19136            app.adjType = "fixed";
19137            app.adjSeq = mAdjSeq;
19138            app.curRawAdj = app.maxAdj;
19139            app.foregroundActivities = false;
19140            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19141            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19142            // System processes can do UI, and when they do we want to have
19143            // them trim their memory after the user leaves the UI.  To
19144            // facilitate this, here we need to determine whether or not it
19145            // is currently showing UI.
19146            app.systemNoUi = true;
19147            if (app == TOP_APP) {
19148                app.systemNoUi = false;
19149                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19150                app.adjType = "pers-top-activity";
19151            } else if (activitiesSize > 0) {
19152                for (int j = 0; j < activitiesSize; j++) {
19153                    final ActivityRecord r = app.activities.get(j);
19154                    if (r.visible) {
19155                        app.systemNoUi = false;
19156                    }
19157                }
19158            }
19159            if (!app.systemNoUi) {
19160                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19161            }
19162            return (app.curAdj=app.maxAdj);
19163        }
19164
19165        app.systemNoUi = false;
19166
19167        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19168
19169        // Determine the importance of the process, starting with most
19170        // important to least, and assign an appropriate OOM adjustment.
19171        int adj;
19172        int schedGroup;
19173        int procState;
19174        boolean foregroundActivities = false;
19175        BroadcastQueue queue;
19176        if (app == TOP_APP) {
19177            // The last app on the list is the foreground app.
19178            adj = ProcessList.FOREGROUND_APP_ADJ;
19179            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19180            app.adjType = "top-activity";
19181            foregroundActivities = true;
19182            procState = PROCESS_STATE_CUR_TOP;
19183        } else if (app.instrumentationClass != null) {
19184            // Don't want to kill running instrumentation.
19185            adj = ProcessList.FOREGROUND_APP_ADJ;
19186            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19187            app.adjType = "instrumentation";
19188            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19189        } else if ((queue = isReceivingBroadcast(app)) != null) {
19190            // An app that is currently receiving a broadcast also
19191            // counts as being in the foreground for OOM killer purposes.
19192            // It's placed in a sched group based on the nature of the
19193            // broadcast as reflected by which queue it's active in.
19194            adj = ProcessList.FOREGROUND_APP_ADJ;
19195            schedGroup = (queue == mFgBroadcastQueue)
19196                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19197            app.adjType = "broadcast";
19198            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19199        } else if (app.executingServices.size() > 0) {
19200            // An app that is currently executing a service callback also
19201            // counts as being in the foreground.
19202            adj = ProcessList.FOREGROUND_APP_ADJ;
19203            schedGroup = app.execServicesFg ?
19204                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19205            app.adjType = "exec-service";
19206            procState = ActivityManager.PROCESS_STATE_SERVICE;
19207            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19208        } else {
19209            // As far as we know the process is empty.  We may change our mind later.
19210            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19211            // At this point we don't actually know the adjustment.  Use the cached adj
19212            // value that the caller wants us to.
19213            adj = cachedAdj;
19214            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19215            app.cached = true;
19216            app.empty = true;
19217            app.adjType = "cch-empty";
19218        }
19219
19220        // Examine all activities if not already foreground.
19221        if (!foregroundActivities && activitiesSize > 0) {
19222            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19223            for (int j = 0; j < activitiesSize; j++) {
19224                final ActivityRecord r = app.activities.get(j);
19225                if (r.app != app) {
19226                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19227                            + " instead of expected " + app);
19228                    if (r.app == null || (r.app.uid == app.uid)) {
19229                        // Only fix things up when they look sane
19230                        r.app = app;
19231                    } else {
19232                        continue;
19233                    }
19234                }
19235                if (r.visible) {
19236                    // App has a visible activity; only upgrade adjustment.
19237                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19238                        adj = ProcessList.VISIBLE_APP_ADJ;
19239                        app.adjType = "visible";
19240                    }
19241                    if (procState > PROCESS_STATE_CUR_TOP) {
19242                        procState = PROCESS_STATE_CUR_TOP;
19243                    }
19244                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19245                    app.cached = false;
19246                    app.empty = false;
19247                    foregroundActivities = true;
19248                    if (r.task != null && minLayer > 0) {
19249                        final int layer = r.task.mLayerRank;
19250                        if (layer >= 0 && minLayer > layer) {
19251                            minLayer = layer;
19252                        }
19253                    }
19254                    break;
19255                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19256                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19257                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19258                        app.adjType = "pausing";
19259                    }
19260                    if (procState > PROCESS_STATE_CUR_TOP) {
19261                        procState = PROCESS_STATE_CUR_TOP;
19262                    }
19263                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19264                    app.cached = false;
19265                    app.empty = false;
19266                    foregroundActivities = true;
19267                } else if (r.state == ActivityState.STOPPING) {
19268                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19269                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19270                        app.adjType = "stopping";
19271                    }
19272                    // For the process state, we will at this point consider the
19273                    // process to be cached.  It will be cached either as an activity
19274                    // or empty depending on whether the activity is finishing.  We do
19275                    // this so that we can treat the process as cached for purposes of
19276                    // memory trimming (determing current memory level, trim command to
19277                    // send to process) since there can be an arbitrary number of stopping
19278                    // processes and they should soon all go into the cached state.
19279                    if (!r.finishing) {
19280                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19281                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19282                        }
19283                    }
19284                    app.cached = false;
19285                    app.empty = false;
19286                    foregroundActivities = true;
19287                } else {
19288                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19289                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19290                        app.adjType = "cch-act";
19291                    }
19292                }
19293            }
19294            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19295                adj += minLayer;
19296            }
19297        }
19298
19299        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19300                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19301            if (app.foregroundServices) {
19302                // The user is aware of this app, so make it visible.
19303                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19304                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19305                app.cached = false;
19306                app.adjType = "fg-service";
19307                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19308            } else if (app.forcingToForeground != null) {
19309                // The user is aware of this app, so make it visible.
19310                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19311                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19312                app.cached = false;
19313                app.adjType = "force-fg";
19314                app.adjSource = app.forcingToForeground;
19315                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19316            }
19317        }
19318
19319        if (app == mHeavyWeightProcess) {
19320            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19321                // We don't want to kill the current heavy-weight process.
19322                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19323                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19324                app.cached = false;
19325                app.adjType = "heavy";
19326            }
19327            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19328                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19329            }
19330        }
19331
19332        if (app == mHomeProcess) {
19333            if (adj > ProcessList.HOME_APP_ADJ) {
19334                // This process is hosting what we currently consider to be the
19335                // home app, so we don't want to let it go into the background.
19336                adj = ProcessList.HOME_APP_ADJ;
19337                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19338                app.cached = false;
19339                app.adjType = "home";
19340            }
19341            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19342                procState = ActivityManager.PROCESS_STATE_HOME;
19343            }
19344        }
19345
19346        if (app == mPreviousProcess && app.activities.size() > 0) {
19347            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19348                // This was the previous process that showed UI to the user.
19349                // We want to try to keep it around more aggressively, to give
19350                // a good experience around switching between two apps.
19351                adj = ProcessList.PREVIOUS_APP_ADJ;
19352                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19353                app.cached = false;
19354                app.adjType = "previous";
19355            }
19356            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19357                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19358            }
19359        }
19360
19361        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19362                + " reason=" + app.adjType);
19363
19364        // By default, we use the computed adjustment.  It may be changed if
19365        // there are applications dependent on our services or providers, but
19366        // this gives us a baseline and makes sure we don't get into an
19367        // infinite recursion.
19368        app.adjSeq = mAdjSeq;
19369        app.curRawAdj = adj;
19370        app.hasStartedServices = false;
19371
19372        if (mBackupTarget != null && app == mBackupTarget.app) {
19373            // If possible we want to avoid killing apps while they're being backed up
19374            if (adj > ProcessList.BACKUP_APP_ADJ) {
19375                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19376                adj = ProcessList.BACKUP_APP_ADJ;
19377                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19378                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19379                }
19380                app.adjType = "backup";
19381                app.cached = false;
19382            }
19383            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19384                procState = ActivityManager.PROCESS_STATE_BACKUP;
19385            }
19386        }
19387
19388        boolean mayBeTop = false;
19389
19390        for (int is = app.services.size()-1;
19391                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19392                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19393                        || procState > ActivityManager.PROCESS_STATE_TOP);
19394                is--) {
19395            ServiceRecord s = app.services.valueAt(is);
19396            if (s.startRequested) {
19397                app.hasStartedServices = true;
19398                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19399                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19400                }
19401                if (app.hasShownUi && app != mHomeProcess) {
19402                    // If this process has shown some UI, let it immediately
19403                    // go to the LRU list because it may be pretty heavy with
19404                    // UI stuff.  We'll tag it with a label just to help
19405                    // debug and understand what is going on.
19406                    if (adj > ProcessList.SERVICE_ADJ) {
19407                        app.adjType = "cch-started-ui-services";
19408                    }
19409                } else {
19410                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19411                        // This service has seen some activity within
19412                        // recent memory, so we will keep its process ahead
19413                        // of the background processes.
19414                        if (adj > ProcessList.SERVICE_ADJ) {
19415                            adj = ProcessList.SERVICE_ADJ;
19416                            app.adjType = "started-services";
19417                            app.cached = false;
19418                        }
19419                    }
19420                    // If we have let the service slide into the background
19421                    // state, still have some text describing what it is doing
19422                    // even though the service no longer has an impact.
19423                    if (adj > ProcessList.SERVICE_ADJ) {
19424                        app.adjType = "cch-started-services";
19425                    }
19426                }
19427            }
19428
19429            for (int conni = s.connections.size()-1;
19430                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19431                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19432                            || procState > ActivityManager.PROCESS_STATE_TOP);
19433                    conni--) {
19434                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19435                for (int i = 0;
19436                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19437                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19438                                || procState > ActivityManager.PROCESS_STATE_TOP);
19439                        i++) {
19440                    // XXX should compute this based on the max of
19441                    // all connected clients.
19442                    ConnectionRecord cr = clist.get(i);
19443                    if (cr.binding.client == app) {
19444                        // Binding to ourself is not interesting.
19445                        continue;
19446                    }
19447
19448                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19449                        ProcessRecord client = cr.binding.client;
19450                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19451                                TOP_APP, doingAll, now);
19452                        int clientProcState = client.curProcState;
19453                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19454                            // If the other app is cached for any reason, for purposes here
19455                            // we are going to consider it empty.  The specific cached state
19456                            // doesn't propagate except under certain conditions.
19457                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19458                        }
19459                        String adjType = null;
19460                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19461                            // Not doing bind OOM management, so treat
19462                            // this guy more like a started service.
19463                            if (app.hasShownUi && app != mHomeProcess) {
19464                                // If this process has shown some UI, let it immediately
19465                                // go to the LRU list because it may be pretty heavy with
19466                                // UI stuff.  We'll tag it with a label just to help
19467                                // debug and understand what is going on.
19468                                if (adj > clientAdj) {
19469                                    adjType = "cch-bound-ui-services";
19470                                }
19471                                app.cached = false;
19472                                clientAdj = adj;
19473                                clientProcState = procState;
19474                            } else {
19475                                if (now >= (s.lastActivity
19476                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19477                                    // This service has not seen activity within
19478                                    // recent memory, so allow it to drop to the
19479                                    // LRU list if there is no other reason to keep
19480                                    // it around.  We'll also tag it with a label just
19481                                    // to help debug and undertand what is going on.
19482                                    if (adj > clientAdj) {
19483                                        adjType = "cch-bound-services";
19484                                    }
19485                                    clientAdj = adj;
19486                                }
19487                            }
19488                        }
19489                        if (adj > clientAdj) {
19490                            // If this process has recently shown UI, and
19491                            // the process that is binding to it is less
19492                            // important than being visible, then we don't
19493                            // care about the binding as much as we care
19494                            // about letting this process get into the LRU
19495                            // list to be killed and restarted if needed for
19496                            // memory.
19497                            if (app.hasShownUi && app != mHomeProcess
19498                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19499                                adjType = "cch-bound-ui-services";
19500                            } else {
19501                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19502                                        |Context.BIND_IMPORTANT)) != 0) {
19503                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19504                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19505                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19506                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19507                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19508                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19509                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19510                                    adj = clientAdj;
19511                                } else {
19512                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19513                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19514                                    }
19515                                }
19516                                if (!client.cached) {
19517                                    app.cached = false;
19518                                }
19519                                adjType = "service";
19520                            }
19521                        }
19522                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19523                            // This will treat important bound services identically to
19524                            // the top app, which may behave differently than generic
19525                            // foreground work.
19526                            if (client.curSchedGroup > schedGroup) {
19527                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19528                                    schedGroup = client.curSchedGroup;
19529                                } else {
19530                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19531                                }
19532                            }
19533                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19534                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19535                                    // Special handling of clients who are in the top state.
19536                                    // We *may* want to consider this process to be in the
19537                                    // top state as well, but only if there is not another
19538                                    // reason for it to be running.  Being on the top is a
19539                                    // special state, meaning you are specifically running
19540                                    // for the current top app.  If the process is already
19541                                    // running in the background for some other reason, it
19542                                    // is more important to continue considering it to be
19543                                    // in the background state.
19544                                    mayBeTop = true;
19545                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19546                                } else {
19547                                    // Special handling for above-top states (persistent
19548                                    // processes).  These should not bring the current process
19549                                    // into the top state, since they are not on top.  Instead
19550                                    // give them the best state after that.
19551                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19552                                        clientProcState =
19553                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19554                                    } else if (mWakefulness
19555                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19556                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19557                                                    != 0) {
19558                                        clientProcState =
19559                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19560                                    } else {
19561                                        clientProcState =
19562                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19563                                    }
19564                                }
19565                            }
19566                        } else {
19567                            if (clientProcState <
19568                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19569                                clientProcState =
19570                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19571                            }
19572                        }
19573                        if (procState > clientProcState) {
19574                            procState = clientProcState;
19575                        }
19576                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19577                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19578                            app.pendingUiClean = true;
19579                        }
19580                        if (adjType != null) {
19581                            app.adjType = adjType;
19582                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19583                                    .REASON_SERVICE_IN_USE;
19584                            app.adjSource = cr.binding.client;
19585                            app.adjSourceProcState = clientProcState;
19586                            app.adjTarget = s.name;
19587                        }
19588                    }
19589                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19590                        app.treatLikeActivity = true;
19591                    }
19592                    final ActivityRecord a = cr.activity;
19593                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19594                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19595                            (a.visible || a.state == ActivityState.RESUMED ||
19596                             a.state == ActivityState.PAUSING)) {
19597                            adj = ProcessList.FOREGROUND_APP_ADJ;
19598                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19599                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19600                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19601                                } else {
19602                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19603                                }
19604                            }
19605                            app.cached = false;
19606                            app.adjType = "service";
19607                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19608                                    .REASON_SERVICE_IN_USE;
19609                            app.adjSource = a;
19610                            app.adjSourceProcState = procState;
19611                            app.adjTarget = s.name;
19612                        }
19613                    }
19614                }
19615            }
19616        }
19617
19618        for (int provi = app.pubProviders.size()-1;
19619                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19620                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19621                        || procState > ActivityManager.PROCESS_STATE_TOP);
19622                provi--) {
19623            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19624            for (int i = cpr.connections.size()-1;
19625                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19626                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19627                            || procState > ActivityManager.PROCESS_STATE_TOP);
19628                    i--) {
19629                ContentProviderConnection conn = cpr.connections.get(i);
19630                ProcessRecord client = conn.client;
19631                if (client == app) {
19632                    // Being our own client is not interesting.
19633                    continue;
19634                }
19635                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19636                int clientProcState = client.curProcState;
19637                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19638                    // If the other app is cached for any reason, for purposes here
19639                    // we are going to consider it empty.
19640                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19641                }
19642                if (adj > clientAdj) {
19643                    if (app.hasShownUi && app != mHomeProcess
19644                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19645                        app.adjType = "cch-ui-provider";
19646                    } else {
19647                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19648                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19649                        app.adjType = "provider";
19650                    }
19651                    app.cached &= client.cached;
19652                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19653                            .REASON_PROVIDER_IN_USE;
19654                    app.adjSource = client;
19655                    app.adjSourceProcState = clientProcState;
19656                    app.adjTarget = cpr.name;
19657                }
19658                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19659                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19660                        // Special handling of clients who are in the top state.
19661                        // We *may* want to consider this process to be in the
19662                        // top state as well, but only if there is not another
19663                        // reason for it to be running.  Being on the top is a
19664                        // special state, meaning you are specifically running
19665                        // for the current top app.  If the process is already
19666                        // running in the background for some other reason, it
19667                        // is more important to continue considering it to be
19668                        // in the background state.
19669                        mayBeTop = true;
19670                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19671                    } else {
19672                        // Special handling for above-top states (persistent
19673                        // processes).  These should not bring the current process
19674                        // into the top state, since they are not on top.  Instead
19675                        // give them the best state after that.
19676                        clientProcState =
19677                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19678                    }
19679                }
19680                if (procState > clientProcState) {
19681                    procState = clientProcState;
19682                }
19683                if (client.curSchedGroup > schedGroup) {
19684                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19685                }
19686            }
19687            // If the provider has external (non-framework) process
19688            // dependencies, ensure that its adjustment is at least
19689            // FOREGROUND_APP_ADJ.
19690            if (cpr.hasExternalProcessHandles()) {
19691                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19692                    adj = ProcessList.FOREGROUND_APP_ADJ;
19693                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19694                    app.cached = false;
19695                    app.adjType = "provider";
19696                    app.adjTarget = cpr.name;
19697                }
19698                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19699                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19700                }
19701            }
19702        }
19703
19704        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19705            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19706                adj = ProcessList.PREVIOUS_APP_ADJ;
19707                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19708                app.cached = false;
19709                app.adjType = "provider";
19710            }
19711            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19712                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19713            }
19714        }
19715
19716        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19717            // A client of one of our services or providers is in the top state.  We
19718            // *may* want to be in the top state, but not if we are already running in
19719            // the background for some other reason.  For the decision here, we are going
19720            // to pick out a few specific states that we want to remain in when a client
19721            // is top (states that tend to be longer-term) and otherwise allow it to go
19722            // to the top state.
19723            switch (procState) {
19724                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19725                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19726                case ActivityManager.PROCESS_STATE_SERVICE:
19727                    // These all are longer-term states, so pull them up to the top
19728                    // of the background states, but not all the way to the top state.
19729                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19730                    break;
19731                default:
19732                    // Otherwise, top is a better choice, so take it.
19733                    procState = ActivityManager.PROCESS_STATE_TOP;
19734                    break;
19735            }
19736        }
19737
19738        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19739            if (app.hasClientActivities) {
19740                // This is a cached process, but with client activities.  Mark it so.
19741                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19742                app.adjType = "cch-client-act";
19743            } else if (app.treatLikeActivity) {
19744                // This is a cached process, but somebody wants us to treat it like it has
19745                // an activity, okay!
19746                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19747                app.adjType = "cch-as-act";
19748            }
19749        }
19750
19751        if (adj == ProcessList.SERVICE_ADJ) {
19752            if (doingAll) {
19753                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19754                mNewNumServiceProcs++;
19755                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19756                if (!app.serviceb) {
19757                    // This service isn't far enough down on the LRU list to
19758                    // normally be a B service, but if we are low on RAM and it
19759                    // is large we want to force it down since we would prefer to
19760                    // keep launcher over it.
19761                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19762                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19763                        app.serviceHighRam = true;
19764                        app.serviceb = true;
19765                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19766                    } else {
19767                        mNewNumAServiceProcs++;
19768                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19769                    }
19770                } else {
19771                    app.serviceHighRam = false;
19772                }
19773            }
19774            if (app.serviceb) {
19775                adj = ProcessList.SERVICE_B_ADJ;
19776            }
19777        }
19778
19779        app.curRawAdj = adj;
19780
19781        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19782        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19783        if (adj > app.maxAdj) {
19784            adj = app.maxAdj;
19785            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19786                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19787            }
19788        }
19789
19790        // Do final modification to adj.  Everything we do between here and applying
19791        // the final setAdj must be done in this function, because we will also use
19792        // it when computing the final cached adj later.  Note that we don't need to
19793        // worry about this for max adj above, since max adj will always be used to
19794        // keep it out of the cached vaues.
19795        app.curAdj = app.modifyRawOomAdj(adj);
19796        app.curSchedGroup = schedGroup;
19797        app.curProcState = procState;
19798        app.foregroundActivities = foregroundActivities;
19799
19800        return app.curRawAdj;
19801    }
19802
19803    /**
19804     * Record new PSS sample for a process.
19805     */
19806    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19807            long now) {
19808        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19809                swapPss * 1024);
19810        proc.lastPssTime = now;
19811        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19812        if (DEBUG_PSS) Slog.d(TAG_PSS,
19813                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19814                + " state=" + ProcessList.makeProcStateString(procState));
19815        if (proc.initialIdlePss == 0) {
19816            proc.initialIdlePss = pss;
19817        }
19818        proc.lastPss = pss;
19819        proc.lastSwapPss = swapPss;
19820        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19821            proc.lastCachedPss = pss;
19822            proc.lastCachedSwapPss = swapPss;
19823        }
19824
19825        final SparseArray<Pair<Long, String>> watchUids
19826                = mMemWatchProcesses.getMap().get(proc.processName);
19827        Long check = null;
19828        if (watchUids != null) {
19829            Pair<Long, String> val = watchUids.get(proc.uid);
19830            if (val == null) {
19831                val = watchUids.get(0);
19832            }
19833            if (val != null) {
19834                check = val.first;
19835            }
19836        }
19837        if (check != null) {
19838            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19839                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19840                if (!isDebuggable) {
19841                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19842                        isDebuggable = true;
19843                    }
19844                }
19845                if (isDebuggable) {
19846                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19847                    final ProcessRecord myProc = proc;
19848                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19849                    mMemWatchDumpProcName = proc.processName;
19850                    mMemWatchDumpFile = heapdumpFile.toString();
19851                    mMemWatchDumpPid = proc.pid;
19852                    mMemWatchDumpUid = proc.uid;
19853                    BackgroundThread.getHandler().post(new Runnable() {
19854                        @Override
19855                        public void run() {
19856                            revokeUriPermission(ActivityThread.currentActivityThread()
19857                                            .getApplicationThread(),
19858                                    DumpHeapActivity.JAVA_URI,
19859                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19860                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19861                                    UserHandle.myUserId());
19862                            ParcelFileDescriptor fd = null;
19863                            try {
19864                                heapdumpFile.delete();
19865                                fd = ParcelFileDescriptor.open(heapdumpFile,
19866                                        ParcelFileDescriptor.MODE_CREATE |
19867                                                ParcelFileDescriptor.MODE_TRUNCATE |
19868                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19869                                                ParcelFileDescriptor.MODE_APPEND);
19870                                IApplicationThread thread = myProc.thread;
19871                                if (thread != null) {
19872                                    try {
19873                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19874                                                "Requesting dump heap from "
19875                                                + myProc + " to " + heapdumpFile);
19876                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19877                                    } catch (RemoteException e) {
19878                                    }
19879                                }
19880                            } catch (FileNotFoundException e) {
19881                                e.printStackTrace();
19882                            } finally {
19883                                if (fd != null) {
19884                                    try {
19885                                        fd.close();
19886                                    } catch (IOException e) {
19887                                    }
19888                                }
19889                            }
19890                        }
19891                    });
19892                } else {
19893                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19894                            + ", but debugging not enabled");
19895                }
19896            }
19897        }
19898    }
19899
19900    /**
19901     * Schedule PSS collection of a process.
19902     */
19903    void requestPssLocked(ProcessRecord proc, int procState) {
19904        if (mPendingPssProcesses.contains(proc)) {
19905            return;
19906        }
19907        if (mPendingPssProcesses.size() == 0) {
19908            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19909        }
19910        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19911        proc.pssProcState = procState;
19912        mPendingPssProcesses.add(proc);
19913    }
19914
19915    /**
19916     * Schedule PSS collection of all processes.
19917     */
19918    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19919        if (!always) {
19920            if (now < (mLastFullPssTime +
19921                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19922                return;
19923            }
19924        }
19925        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19926        mLastFullPssTime = now;
19927        mFullPssPending = true;
19928        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19929        mPendingPssProcesses.clear();
19930        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19931            ProcessRecord app = mLruProcesses.get(i);
19932            if (app.thread == null
19933                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19934                continue;
19935            }
19936            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19937                app.pssProcState = app.setProcState;
19938                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19939                        mTestPssMode, isSleepingLocked(), now);
19940                mPendingPssProcesses.add(app);
19941            }
19942        }
19943        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19944    }
19945
19946    public void setTestPssMode(boolean enabled) {
19947        synchronized (this) {
19948            mTestPssMode = enabled;
19949            if (enabled) {
19950                // Whenever we enable the mode, we want to take a snapshot all of current
19951                // process mem use.
19952                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19953            }
19954        }
19955    }
19956
19957    /**
19958     * Ask a given process to GC right now.
19959     */
19960    final void performAppGcLocked(ProcessRecord app) {
19961        try {
19962            app.lastRequestedGc = SystemClock.uptimeMillis();
19963            if (app.thread != null) {
19964                if (app.reportLowMemory) {
19965                    app.reportLowMemory = false;
19966                    app.thread.scheduleLowMemory();
19967                } else {
19968                    app.thread.processInBackground();
19969                }
19970            }
19971        } catch (Exception e) {
19972            // whatever.
19973        }
19974    }
19975
19976    /**
19977     * Returns true if things are idle enough to perform GCs.
19978     */
19979    private final boolean canGcNowLocked() {
19980        boolean processingBroadcasts = false;
19981        for (BroadcastQueue q : mBroadcastQueues) {
19982            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19983                processingBroadcasts = true;
19984            }
19985        }
19986        return !processingBroadcasts
19987                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19988    }
19989
19990    /**
19991     * Perform GCs on all processes that are waiting for it, but only
19992     * if things are idle.
19993     */
19994    final void performAppGcsLocked() {
19995        final int N = mProcessesToGc.size();
19996        if (N <= 0) {
19997            return;
19998        }
19999        if (canGcNowLocked()) {
20000            while (mProcessesToGc.size() > 0) {
20001                ProcessRecord proc = mProcessesToGc.remove(0);
20002                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20003                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20004                            <= SystemClock.uptimeMillis()) {
20005                        // To avoid spamming the system, we will GC processes one
20006                        // at a time, waiting a few seconds between each.
20007                        performAppGcLocked(proc);
20008                        scheduleAppGcsLocked();
20009                        return;
20010                    } else {
20011                        // It hasn't been long enough since we last GCed this
20012                        // process...  put it in the list to wait for its time.
20013                        addProcessToGcListLocked(proc);
20014                        break;
20015                    }
20016                }
20017            }
20018
20019            scheduleAppGcsLocked();
20020        }
20021    }
20022
20023    /**
20024     * If all looks good, perform GCs on all processes waiting for them.
20025     */
20026    final void performAppGcsIfAppropriateLocked() {
20027        if (canGcNowLocked()) {
20028            performAppGcsLocked();
20029            return;
20030        }
20031        // Still not idle, wait some more.
20032        scheduleAppGcsLocked();
20033    }
20034
20035    /**
20036     * Schedule the execution of all pending app GCs.
20037     */
20038    final void scheduleAppGcsLocked() {
20039        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20040
20041        if (mProcessesToGc.size() > 0) {
20042            // Schedule a GC for the time to the next process.
20043            ProcessRecord proc = mProcessesToGc.get(0);
20044            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20045
20046            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20047            long now = SystemClock.uptimeMillis();
20048            if (when < (now+GC_TIMEOUT)) {
20049                when = now + GC_TIMEOUT;
20050            }
20051            mHandler.sendMessageAtTime(msg, when);
20052        }
20053    }
20054
20055    /**
20056     * Add a process to the array of processes waiting to be GCed.  Keeps the
20057     * list in sorted order by the last GC time.  The process can't already be
20058     * on the list.
20059     */
20060    final void addProcessToGcListLocked(ProcessRecord proc) {
20061        boolean added = false;
20062        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20063            if (mProcessesToGc.get(i).lastRequestedGc <
20064                    proc.lastRequestedGc) {
20065                added = true;
20066                mProcessesToGc.add(i+1, proc);
20067                break;
20068            }
20069        }
20070        if (!added) {
20071            mProcessesToGc.add(0, proc);
20072        }
20073    }
20074
20075    /**
20076     * Set up to ask a process to GC itself.  This will either do it
20077     * immediately, or put it on the list of processes to gc the next
20078     * time things are idle.
20079     */
20080    final void scheduleAppGcLocked(ProcessRecord app) {
20081        long now = SystemClock.uptimeMillis();
20082        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20083            return;
20084        }
20085        if (!mProcessesToGc.contains(app)) {
20086            addProcessToGcListLocked(app);
20087            scheduleAppGcsLocked();
20088        }
20089    }
20090
20091    final void checkExcessivePowerUsageLocked(boolean doKills) {
20092        updateCpuStatsNow();
20093
20094        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20095        boolean doWakeKills = doKills;
20096        boolean doCpuKills = doKills;
20097        if (mLastPowerCheckRealtime == 0) {
20098            doWakeKills = false;
20099        }
20100        if (mLastPowerCheckUptime == 0) {
20101            doCpuKills = false;
20102        }
20103        if (stats.isScreenOn()) {
20104            doWakeKills = false;
20105        }
20106        final long curRealtime = SystemClock.elapsedRealtime();
20107        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20108        final long curUptime = SystemClock.uptimeMillis();
20109        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20110        mLastPowerCheckRealtime = curRealtime;
20111        mLastPowerCheckUptime = curUptime;
20112        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20113            doWakeKills = false;
20114        }
20115        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20116            doCpuKills = false;
20117        }
20118        int i = mLruProcesses.size();
20119        while (i > 0) {
20120            i--;
20121            ProcessRecord app = mLruProcesses.get(i);
20122            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20123                long wtime;
20124                synchronized (stats) {
20125                    wtime = stats.getProcessWakeTime(app.info.uid,
20126                            app.pid, curRealtime);
20127                }
20128                long wtimeUsed = wtime - app.lastWakeTime;
20129                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20130                if (DEBUG_POWER) {
20131                    StringBuilder sb = new StringBuilder(128);
20132                    sb.append("Wake for ");
20133                    app.toShortString(sb);
20134                    sb.append(": over ");
20135                    TimeUtils.formatDuration(realtimeSince, sb);
20136                    sb.append(" used ");
20137                    TimeUtils.formatDuration(wtimeUsed, sb);
20138                    sb.append(" (");
20139                    sb.append((wtimeUsed*100)/realtimeSince);
20140                    sb.append("%)");
20141                    Slog.i(TAG_POWER, sb.toString());
20142                    sb.setLength(0);
20143                    sb.append("CPU for ");
20144                    app.toShortString(sb);
20145                    sb.append(": over ");
20146                    TimeUtils.formatDuration(uptimeSince, sb);
20147                    sb.append(" used ");
20148                    TimeUtils.formatDuration(cputimeUsed, sb);
20149                    sb.append(" (");
20150                    sb.append((cputimeUsed*100)/uptimeSince);
20151                    sb.append("%)");
20152                    Slog.i(TAG_POWER, sb.toString());
20153                }
20154                // If a process has held a wake lock for more
20155                // than 50% of the time during this period,
20156                // that sounds bad.  Kill!
20157                if (doWakeKills && realtimeSince > 0
20158                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20159                    synchronized (stats) {
20160                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20161                                realtimeSince, wtimeUsed);
20162                    }
20163                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20164                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20165                } else if (doCpuKills && uptimeSince > 0
20166                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20167                    synchronized (stats) {
20168                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20169                                uptimeSince, cputimeUsed);
20170                    }
20171                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20172                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20173                } else {
20174                    app.lastWakeTime = wtime;
20175                    app.lastCpuTime = app.curCpuTime;
20176                }
20177            }
20178        }
20179    }
20180
20181    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20182            long nowElapsed) {
20183        boolean success = true;
20184
20185        if (app.curRawAdj != app.setRawAdj) {
20186            app.setRawAdj = app.curRawAdj;
20187        }
20188
20189        int changes = 0;
20190
20191        if (app.curAdj != app.setAdj) {
20192            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20193            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20194                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20195                    + app.adjType);
20196            app.setAdj = app.curAdj;
20197            app.verifiedAdj = ProcessList.INVALID_ADJ;
20198        }
20199
20200        if (app.setSchedGroup != app.curSchedGroup) {
20201            int oldSchedGroup = app.setSchedGroup;
20202            app.setSchedGroup = app.curSchedGroup;
20203            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20204                    "Setting sched group of " + app.processName
20205                    + " to " + app.curSchedGroup);
20206            if (app.waitingToKill != null && app.curReceiver == null
20207                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20208                app.kill(app.waitingToKill, true);
20209                success = false;
20210            } else {
20211                int processGroup;
20212                switch (app.curSchedGroup) {
20213                    case ProcessList.SCHED_GROUP_BACKGROUND:
20214                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20215                        break;
20216                    case ProcessList.SCHED_GROUP_TOP_APP:
20217                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20218                        processGroup = Process.THREAD_GROUP_TOP_APP;
20219                        break;
20220                    default:
20221                        processGroup = Process.THREAD_GROUP_DEFAULT;
20222                        break;
20223                }
20224                long oldId = Binder.clearCallingIdentity();
20225                try {
20226                    Process.setProcessGroup(app.pid, processGroup);
20227                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20228                        // do nothing if we already switched to RT
20229                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20230                            // Switch VR thread for app to SCHED_FIFO
20231                            if (mInVrMode && app.vrThreadTid != 0) {
20232                                Process.setThreadScheduler(app.vrThreadTid,
20233                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20234                            }
20235                            if (mUseFifoUiScheduling) {
20236                                // Switch UI pipeline for app to SCHED_FIFO
20237                                app.savedPriority = Process.getThreadPriority(app.pid);
20238                                Process.setThreadScheduler(app.pid,
20239                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20240                                if (app.renderThreadTid != 0) {
20241                                    Process.setThreadScheduler(app.renderThreadTid,
20242                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20243                                    if (DEBUG_OOM_ADJ) {
20244                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20245                                            app.renderThreadTid + ") to FIFO");
20246                                    }
20247                                } else {
20248                                    if (DEBUG_OOM_ADJ) {
20249                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20250                                    }
20251                                }
20252                            }
20253                        }
20254                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20255                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20256                        // Reset VR thread to SCHED_OTHER
20257                        // Safe to do even if we're not in VR mode
20258                        if (app.vrThreadTid != 0) {
20259                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20260                        }
20261                        if (mUseFifoUiScheduling) {
20262                            // Reset UI pipeline to SCHED_OTHER
20263                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20264                            Process.setThreadScheduler(app.renderThreadTid,
20265                                Process.SCHED_OTHER, 0);
20266                            Process.setThreadPriority(app.pid, app.savedPriority);
20267                            Process.setThreadPriority(app.renderThreadTid, -4);
20268                        }
20269                    }
20270                } catch (Exception e) {
20271                    Slog.w(TAG, "Failed setting process group of " + app.pid
20272                            + " to " + app.curSchedGroup);
20273                    e.printStackTrace();
20274                } finally {
20275                    Binder.restoreCallingIdentity(oldId);
20276                }
20277            }
20278        }
20279        if (app.repForegroundActivities != app.foregroundActivities) {
20280            app.repForegroundActivities = app.foregroundActivities;
20281            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20282        }
20283        if (app.repProcState != app.curProcState) {
20284            app.repProcState = app.curProcState;
20285            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20286            if (app.thread != null) {
20287                try {
20288                    if (false) {
20289                        //RuntimeException h = new RuntimeException("here");
20290                        Slog.i(TAG, "Sending new process state " + app.repProcState
20291                                + " to " + app /*, h*/);
20292                    }
20293                    app.thread.setProcessState(app.repProcState);
20294                } catch (RemoteException e) {
20295                }
20296            }
20297        }
20298        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20299                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20300            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20301                // Experimental code to more aggressively collect pss while
20302                // running test...  the problem is that this tends to collect
20303                // the data right when a process is transitioning between process
20304                // states, which well tend to give noisy data.
20305                long start = SystemClock.uptimeMillis();
20306                long pss = Debug.getPss(app.pid, mTmpLong, null);
20307                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20308                mPendingPssProcesses.remove(app);
20309                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20310                        + " to " + app.curProcState + ": "
20311                        + (SystemClock.uptimeMillis()-start) + "ms");
20312            }
20313            app.lastStateTime = now;
20314            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20315                    mTestPssMode, isSleepingLocked(), now);
20316            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20317                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20318                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20319                    + (app.nextPssTime-now) + ": " + app);
20320        } else {
20321            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20322                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20323                    mTestPssMode)))) {
20324                requestPssLocked(app, app.setProcState);
20325                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20326                        mTestPssMode, isSleepingLocked(), now);
20327            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20328                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20329        }
20330        if (app.setProcState != app.curProcState) {
20331            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20332                    "Proc state change of " + app.processName
20333                            + " to " + app.curProcState);
20334            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20335            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20336            if (setImportant && !curImportant) {
20337                // This app is no longer something we consider important enough to allow to
20338                // use arbitrary amounts of battery power.  Note
20339                // its current wake lock time to later know to kill it if
20340                // it is not behaving well.
20341                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20342                synchronized (stats) {
20343                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20344                            app.pid, nowElapsed);
20345                }
20346                app.lastCpuTime = app.curCpuTime;
20347
20348            }
20349            // Inform UsageStats of important process state change
20350            // Must be called before updating setProcState
20351            maybeUpdateUsageStatsLocked(app, nowElapsed);
20352
20353            app.setProcState = app.curProcState;
20354            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20355                app.notCachedSinceIdle = false;
20356            }
20357            if (!doingAll) {
20358                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20359            } else {
20360                app.procStateChanged = true;
20361            }
20362        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20363                > USAGE_STATS_INTERACTION_INTERVAL) {
20364            // For apps that sit around for a long time in the interactive state, we need
20365            // to report this at least once a day so they don't go idle.
20366            maybeUpdateUsageStatsLocked(app, nowElapsed);
20367        }
20368
20369        if (changes != 0) {
20370            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20371                    "Changes in " + app + ": " + changes);
20372            int i = mPendingProcessChanges.size()-1;
20373            ProcessChangeItem item = null;
20374            while (i >= 0) {
20375                item = mPendingProcessChanges.get(i);
20376                if (item.pid == app.pid) {
20377                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20378                            "Re-using existing item: " + item);
20379                    break;
20380                }
20381                i--;
20382            }
20383            if (i < 0) {
20384                // No existing item in pending changes; need a new one.
20385                final int NA = mAvailProcessChanges.size();
20386                if (NA > 0) {
20387                    item = mAvailProcessChanges.remove(NA-1);
20388                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20389                            "Retrieving available item: " + item);
20390                } else {
20391                    item = new ProcessChangeItem();
20392                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20393                            "Allocating new item: " + item);
20394                }
20395                item.changes = 0;
20396                item.pid = app.pid;
20397                item.uid = app.info.uid;
20398                if (mPendingProcessChanges.size() == 0) {
20399                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20400                            "*** Enqueueing dispatch processes changed!");
20401                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20402                }
20403                mPendingProcessChanges.add(item);
20404            }
20405            item.changes |= changes;
20406            item.processState = app.repProcState;
20407            item.foregroundActivities = app.repForegroundActivities;
20408            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20409                    "Item " + Integer.toHexString(System.identityHashCode(item))
20410                    + " " + app.toShortString() + ": changes=" + item.changes
20411                    + " procState=" + item.processState
20412                    + " foreground=" + item.foregroundActivities
20413                    + " type=" + app.adjType + " source=" + app.adjSource
20414                    + " target=" + app.adjTarget);
20415        }
20416
20417        return success;
20418    }
20419
20420    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20421        final UidRecord.ChangeItem pendingChange;
20422        if (uidRec == null || uidRec.pendingChange == null) {
20423            if (mPendingUidChanges.size() == 0) {
20424                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20425                        "*** Enqueueing dispatch uid changed!");
20426                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20427            }
20428            final int NA = mAvailUidChanges.size();
20429            if (NA > 0) {
20430                pendingChange = mAvailUidChanges.remove(NA-1);
20431                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20432                        "Retrieving available item: " + pendingChange);
20433            } else {
20434                pendingChange = new UidRecord.ChangeItem();
20435                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20436                        "Allocating new item: " + pendingChange);
20437            }
20438            if (uidRec != null) {
20439                uidRec.pendingChange = pendingChange;
20440                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20441                    // If this uid is going away, and we haven't yet reported it is gone,
20442                    // then do so now.
20443                    change = UidRecord.CHANGE_GONE_IDLE;
20444                }
20445            } else if (uid < 0) {
20446                throw new IllegalArgumentException("No UidRecord or uid");
20447            }
20448            pendingChange.uidRecord = uidRec;
20449            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20450            mPendingUidChanges.add(pendingChange);
20451        } else {
20452            pendingChange = uidRec.pendingChange;
20453            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20454                change = UidRecord.CHANGE_GONE_IDLE;
20455            }
20456        }
20457        pendingChange.change = change;
20458        pendingChange.processState = uidRec != null
20459                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20460    }
20461
20462    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20463            String authority) {
20464        if (app == null) return;
20465        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20466            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20467            if (userState == null) return;
20468            final long now = SystemClock.elapsedRealtime();
20469            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20470            if (lastReported == null || lastReported < now - 60 * 1000L) {
20471                mUsageStatsService.reportContentProviderUsage(
20472                        authority, providerPkgName, app.userId);
20473                userState.mProviderLastReportedFg.put(authority, now);
20474            }
20475        }
20476    }
20477
20478    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20479        if (DEBUG_USAGE_STATS) {
20480            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20481                    + "] state changes: old = " + app.setProcState + ", new = "
20482                    + app.curProcState);
20483        }
20484        if (mUsageStatsService == null) {
20485            return;
20486        }
20487        boolean isInteraction;
20488        // To avoid some abuse patterns, we are going to be careful about what we consider
20489        // to be an app interaction.  Being the top activity doesn't count while the display
20490        // is sleeping, nor do short foreground services.
20491        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20492            isInteraction = true;
20493            app.fgInteractionTime = 0;
20494        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20495            if (app.fgInteractionTime == 0) {
20496                app.fgInteractionTime = nowElapsed;
20497                isInteraction = false;
20498            } else {
20499                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20500            }
20501        } else {
20502            isInteraction = app.curProcState
20503                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20504            app.fgInteractionTime = 0;
20505        }
20506        if (isInteraction && (!app.reportedInteraction
20507                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20508            app.interactionEventTime = nowElapsed;
20509            String[] packages = app.getPackageList();
20510            if (packages != null) {
20511                for (int i = 0; i < packages.length; i++) {
20512                    mUsageStatsService.reportEvent(packages[i], app.userId,
20513                            UsageEvents.Event.SYSTEM_INTERACTION);
20514                }
20515            }
20516        }
20517        app.reportedInteraction = isInteraction;
20518        if (!isInteraction) {
20519            app.interactionEventTime = 0;
20520        }
20521    }
20522
20523    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20524        if (proc.thread != null) {
20525            if (proc.baseProcessTracker != null) {
20526                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20527            }
20528        }
20529    }
20530
20531    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20532            ProcessRecord TOP_APP, boolean doingAll, long now) {
20533        if (app.thread == null) {
20534            return false;
20535        }
20536
20537        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20538
20539        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20540    }
20541
20542    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20543            boolean oomAdj) {
20544        if (isForeground != proc.foregroundServices) {
20545            proc.foregroundServices = isForeground;
20546            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20547                    proc.info.uid);
20548            if (isForeground) {
20549                if (curProcs == null) {
20550                    curProcs = new ArrayList<ProcessRecord>();
20551                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20552                }
20553                if (!curProcs.contains(proc)) {
20554                    curProcs.add(proc);
20555                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20556                            proc.info.packageName, proc.info.uid);
20557                }
20558            } else {
20559                if (curProcs != null) {
20560                    if (curProcs.remove(proc)) {
20561                        mBatteryStatsService.noteEvent(
20562                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20563                                proc.info.packageName, proc.info.uid);
20564                        if (curProcs.size() <= 0) {
20565                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20566                        }
20567                    }
20568                }
20569            }
20570            if (oomAdj) {
20571                updateOomAdjLocked();
20572            }
20573        }
20574    }
20575
20576    private final ActivityRecord resumedAppLocked() {
20577        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20578        String pkg;
20579        int uid;
20580        if (act != null) {
20581            pkg = act.packageName;
20582            uid = act.info.applicationInfo.uid;
20583        } else {
20584            pkg = null;
20585            uid = -1;
20586        }
20587        // Has the UID or resumed package name changed?
20588        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20589                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20590            if (mCurResumedPackage != null) {
20591                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20592                        mCurResumedPackage, mCurResumedUid);
20593            }
20594            mCurResumedPackage = pkg;
20595            mCurResumedUid = uid;
20596            if (mCurResumedPackage != null) {
20597                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20598                        mCurResumedPackage, mCurResumedUid);
20599            }
20600        }
20601        return act;
20602    }
20603
20604    final boolean updateOomAdjLocked(ProcessRecord app) {
20605        final ActivityRecord TOP_ACT = resumedAppLocked();
20606        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20607        final boolean wasCached = app.cached;
20608
20609        mAdjSeq++;
20610
20611        // This is the desired cached adjusment we want to tell it to use.
20612        // If our app is currently cached, we know it, and that is it.  Otherwise,
20613        // we don't know it yet, and it needs to now be cached we will then
20614        // need to do a complete oom adj.
20615        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20616                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20617        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20618                SystemClock.uptimeMillis());
20619        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20620            // Changed to/from cached state, so apps after it in the LRU
20621            // list may also be changed.
20622            updateOomAdjLocked();
20623        }
20624        return success;
20625    }
20626
20627    final void updateOomAdjLocked() {
20628        final ActivityRecord TOP_ACT = resumedAppLocked();
20629        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20630        final long now = SystemClock.uptimeMillis();
20631        final long nowElapsed = SystemClock.elapsedRealtime();
20632        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20633        final int N = mLruProcesses.size();
20634
20635        if (false) {
20636            RuntimeException e = new RuntimeException();
20637            e.fillInStackTrace();
20638            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20639        }
20640
20641        // Reset state in all uid records.
20642        for (int i=mActiveUids.size()-1; i>=0; i--) {
20643            final UidRecord uidRec = mActiveUids.valueAt(i);
20644            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20645                    "Starting update of " + uidRec);
20646            uidRec.reset();
20647        }
20648
20649        mStackSupervisor.rankTaskLayersIfNeeded();
20650
20651        mAdjSeq++;
20652        mNewNumServiceProcs = 0;
20653        mNewNumAServiceProcs = 0;
20654
20655        final int emptyProcessLimit;
20656        final int cachedProcessLimit;
20657        if (mProcessLimit <= 0) {
20658            emptyProcessLimit = cachedProcessLimit = 0;
20659        } else if (mProcessLimit == 1) {
20660            emptyProcessLimit = 1;
20661            cachedProcessLimit = 0;
20662        } else {
20663            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20664            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20665        }
20666
20667        // Let's determine how many processes we have running vs.
20668        // how many slots we have for background processes; we may want
20669        // to put multiple processes in a slot of there are enough of
20670        // them.
20671        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20672                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20673        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20674        if (numEmptyProcs > cachedProcessLimit) {
20675            // If there are more empty processes than our limit on cached
20676            // processes, then use the cached process limit for the factor.
20677            // This ensures that the really old empty processes get pushed
20678            // down to the bottom, so if we are running low on memory we will
20679            // have a better chance at keeping around more cached processes
20680            // instead of a gazillion empty processes.
20681            numEmptyProcs = cachedProcessLimit;
20682        }
20683        int emptyFactor = numEmptyProcs/numSlots;
20684        if (emptyFactor < 1) emptyFactor = 1;
20685        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20686        if (cachedFactor < 1) cachedFactor = 1;
20687        int stepCached = 0;
20688        int stepEmpty = 0;
20689        int numCached = 0;
20690        int numEmpty = 0;
20691        int numTrimming = 0;
20692
20693        mNumNonCachedProcs = 0;
20694        mNumCachedHiddenProcs = 0;
20695
20696        // First update the OOM adjustment for each of the
20697        // application processes based on their current state.
20698        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20699        int nextCachedAdj = curCachedAdj+1;
20700        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20701        int nextEmptyAdj = curEmptyAdj+2;
20702        for (int i=N-1; i>=0; i--) {
20703            ProcessRecord app = mLruProcesses.get(i);
20704            if (!app.killedByAm && app.thread != null) {
20705                app.procStateChanged = false;
20706                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20707
20708                // If we haven't yet assigned the final cached adj
20709                // to the process, do that now.
20710                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20711                    switch (app.curProcState) {
20712                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20713                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20714                            // This process is a cached process holding activities...
20715                            // assign it the next cached value for that type, and then
20716                            // step that cached level.
20717                            app.curRawAdj = curCachedAdj;
20718                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20719                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20720                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20721                                    + ")");
20722                            if (curCachedAdj != nextCachedAdj) {
20723                                stepCached++;
20724                                if (stepCached >= cachedFactor) {
20725                                    stepCached = 0;
20726                                    curCachedAdj = nextCachedAdj;
20727                                    nextCachedAdj += 2;
20728                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20729                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20730                                    }
20731                                }
20732                            }
20733                            break;
20734                        default:
20735                            // For everything else, assign next empty cached process
20736                            // level and bump that up.  Note that this means that
20737                            // long-running services that have dropped down to the
20738                            // cached level will be treated as empty (since their process
20739                            // state is still as a service), which is what we want.
20740                            app.curRawAdj = curEmptyAdj;
20741                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20742                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20743                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20744                                    + ")");
20745                            if (curEmptyAdj != nextEmptyAdj) {
20746                                stepEmpty++;
20747                                if (stepEmpty >= emptyFactor) {
20748                                    stepEmpty = 0;
20749                                    curEmptyAdj = nextEmptyAdj;
20750                                    nextEmptyAdj += 2;
20751                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20752                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20753                                    }
20754                                }
20755                            }
20756                            break;
20757                    }
20758                }
20759
20760                applyOomAdjLocked(app, true, now, nowElapsed);
20761
20762                // Count the number of process types.
20763                switch (app.curProcState) {
20764                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20765                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20766                        mNumCachedHiddenProcs++;
20767                        numCached++;
20768                        if (numCached > cachedProcessLimit) {
20769                            app.kill("cached #" + numCached, true);
20770                        }
20771                        break;
20772                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20773                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20774                                && app.lastActivityTime < oldTime) {
20775                            app.kill("empty for "
20776                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20777                                    / 1000) + "s", true);
20778                        } else {
20779                            numEmpty++;
20780                            if (numEmpty > emptyProcessLimit) {
20781                                app.kill("empty #" + numEmpty, true);
20782                            }
20783                        }
20784                        break;
20785                    default:
20786                        mNumNonCachedProcs++;
20787                        break;
20788                }
20789
20790                if (app.isolated && app.services.size() <= 0) {
20791                    // If this is an isolated process, and there are no
20792                    // services running in it, then the process is no longer
20793                    // needed.  We agressively kill these because we can by
20794                    // definition not re-use the same process again, and it is
20795                    // good to avoid having whatever code was running in them
20796                    // left sitting around after no longer needed.
20797                    app.kill("isolated not needed", true);
20798                } else {
20799                    // Keeping this process, update its uid.
20800                    final UidRecord uidRec = app.uidRecord;
20801                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20802                        uidRec.curProcState = app.curProcState;
20803                    }
20804                }
20805
20806                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20807                        && !app.killedByAm) {
20808                    numTrimming++;
20809                }
20810            }
20811        }
20812
20813        mNumServiceProcs = mNewNumServiceProcs;
20814
20815        // Now determine the memory trimming level of background processes.
20816        // Unfortunately we need to start at the back of the list to do this
20817        // properly.  We only do this if the number of background apps we
20818        // are managing to keep around is less than half the maximum we desire;
20819        // if we are keeping a good number around, we'll let them use whatever
20820        // memory they want.
20821        final int numCachedAndEmpty = numCached + numEmpty;
20822        int memFactor;
20823        if (numCached <= ProcessList.TRIM_CACHED_APPS
20824                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20825            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20826                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20827            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20828                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20829            } else {
20830                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20831            }
20832        } else {
20833            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20834        }
20835        // We always allow the memory level to go up (better).  We only allow it to go
20836        // down if we are in a state where that is allowed, *and* the total number of processes
20837        // has gone down since last time.
20838        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20839                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20840                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20841        if (memFactor > mLastMemoryLevel) {
20842            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20843                memFactor = mLastMemoryLevel;
20844                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20845            }
20846        }
20847        if (memFactor != mLastMemoryLevel) {
20848            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20849        }
20850        mLastMemoryLevel = memFactor;
20851        mLastNumProcesses = mLruProcesses.size();
20852        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20853        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20854        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20855            if (mLowRamStartTime == 0) {
20856                mLowRamStartTime = now;
20857            }
20858            int step = 0;
20859            int fgTrimLevel;
20860            switch (memFactor) {
20861                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20862                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20863                    break;
20864                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20865                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20866                    break;
20867                default:
20868                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20869                    break;
20870            }
20871            int factor = numTrimming/3;
20872            int minFactor = 2;
20873            if (mHomeProcess != null) minFactor++;
20874            if (mPreviousProcess != null) minFactor++;
20875            if (factor < minFactor) factor = minFactor;
20876            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20877            for (int i=N-1; i>=0; i--) {
20878                ProcessRecord app = mLruProcesses.get(i);
20879                if (allChanged || app.procStateChanged) {
20880                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20881                    app.procStateChanged = false;
20882                }
20883                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20884                        && !app.killedByAm) {
20885                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20886                        try {
20887                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20888                                    "Trimming memory of " + app.processName + " to " + curLevel);
20889                            app.thread.scheduleTrimMemory(curLevel);
20890                        } catch (RemoteException e) {
20891                        }
20892                        if (false) {
20893                            // For now we won't do this; our memory trimming seems
20894                            // to be good enough at this point that destroying
20895                            // activities causes more harm than good.
20896                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20897                                    && app != mHomeProcess && app != mPreviousProcess) {
20898                                // Need to do this on its own message because the stack may not
20899                                // be in a consistent state at this point.
20900                                // For these apps we will also finish their activities
20901                                // to help them free memory.
20902                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20903                            }
20904                        }
20905                    }
20906                    app.trimMemoryLevel = curLevel;
20907                    step++;
20908                    if (step >= factor) {
20909                        step = 0;
20910                        switch (curLevel) {
20911                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20912                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20913                                break;
20914                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20915                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20916                                break;
20917                        }
20918                    }
20919                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20920                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20921                            && app.thread != null) {
20922                        try {
20923                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20924                                    "Trimming memory of heavy-weight " + app.processName
20925                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20926                            app.thread.scheduleTrimMemory(
20927                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20928                        } catch (RemoteException e) {
20929                        }
20930                    }
20931                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20932                } else {
20933                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20934                            || app.systemNoUi) && app.pendingUiClean) {
20935                        // If this application is now in the background and it
20936                        // had done UI, then give it the special trim level to
20937                        // have it free UI resources.
20938                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20939                        if (app.trimMemoryLevel < level && app.thread != null) {
20940                            try {
20941                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20942                                        "Trimming memory of bg-ui " + app.processName
20943                                        + " to " + level);
20944                                app.thread.scheduleTrimMemory(level);
20945                            } catch (RemoteException e) {
20946                            }
20947                        }
20948                        app.pendingUiClean = false;
20949                    }
20950                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20951                        try {
20952                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20953                                    "Trimming memory of fg " + app.processName
20954                                    + " to " + fgTrimLevel);
20955                            app.thread.scheduleTrimMemory(fgTrimLevel);
20956                        } catch (RemoteException e) {
20957                        }
20958                    }
20959                    app.trimMemoryLevel = fgTrimLevel;
20960                }
20961            }
20962        } else {
20963            if (mLowRamStartTime != 0) {
20964                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20965                mLowRamStartTime = 0;
20966            }
20967            for (int i=N-1; i>=0; i--) {
20968                ProcessRecord app = mLruProcesses.get(i);
20969                if (allChanged || app.procStateChanged) {
20970                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20971                    app.procStateChanged = false;
20972                }
20973                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20974                        || app.systemNoUi) && app.pendingUiClean) {
20975                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20976                            && app.thread != null) {
20977                        try {
20978                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20979                                    "Trimming memory of ui hidden " + app.processName
20980                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20981                            app.thread.scheduleTrimMemory(
20982                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20983                        } catch (RemoteException e) {
20984                        }
20985                    }
20986                    app.pendingUiClean = false;
20987                }
20988                app.trimMemoryLevel = 0;
20989            }
20990        }
20991
20992        if (mAlwaysFinishActivities) {
20993            // Need to do this on its own message because the stack may not
20994            // be in a consistent state at this point.
20995            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20996        }
20997
20998        if (allChanged) {
20999            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21000        }
21001
21002        // Update from any uid changes.
21003        for (int i=mActiveUids.size()-1; i>=0; i--) {
21004            final UidRecord uidRec = mActiveUids.valueAt(i);
21005            int uidChange = UidRecord.CHANGE_PROCSTATE;
21006            if (uidRec.setProcState != uidRec.curProcState) {
21007                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21008                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21009                        + " to " + uidRec.curProcState);
21010                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21011                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21012                        uidRec.lastBackgroundTime = nowElapsed;
21013                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21014                            // Note: the background settle time is in elapsed realtime, while
21015                            // the handler time base is uptime.  All this means is that we may
21016                            // stop background uids later than we had intended, but that only
21017                            // happens because the device was sleeping so we are okay anyway.
21018                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21019                        }
21020                    }
21021                } else {
21022                    if (uidRec.idle) {
21023                        uidChange = UidRecord.CHANGE_ACTIVE;
21024                        uidRec.idle = false;
21025                    }
21026                    uidRec.lastBackgroundTime = 0;
21027                }
21028                uidRec.setProcState = uidRec.curProcState;
21029                enqueueUidChangeLocked(uidRec, -1, uidChange);
21030                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21031            }
21032        }
21033
21034        if (mProcessStats.shouldWriteNowLocked(now)) {
21035            mHandler.post(new Runnable() {
21036                @Override public void run() {
21037                    synchronized (ActivityManagerService.this) {
21038                        mProcessStats.writeStateAsyncLocked();
21039                    }
21040                }
21041            });
21042        }
21043
21044        if (DEBUG_OOM_ADJ) {
21045            final long duration = SystemClock.uptimeMillis() - now;
21046            if (false) {
21047                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21048                        new RuntimeException("here").fillInStackTrace());
21049            } else {
21050                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21051            }
21052        }
21053    }
21054
21055    final void idleUids() {
21056        synchronized (this) {
21057            final long nowElapsed = SystemClock.elapsedRealtime();
21058            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21059            long nextTime = 0;
21060            for (int i=mActiveUids.size()-1; i>=0; i--) {
21061                final UidRecord uidRec = mActiveUids.valueAt(i);
21062                final long bgTime = uidRec.lastBackgroundTime;
21063                if (bgTime > 0 && !uidRec.idle) {
21064                    if (bgTime <= maxBgTime) {
21065                        uidRec.idle = true;
21066                        doStopUidLocked(uidRec.uid, uidRec);
21067                    } else {
21068                        if (nextTime == 0 || nextTime > bgTime) {
21069                            nextTime = bgTime;
21070                        }
21071                    }
21072                }
21073            }
21074            if (nextTime > 0) {
21075                mHandler.removeMessages(IDLE_UIDS_MSG);
21076                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21077                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21078            }
21079        }
21080    }
21081
21082    final void runInBackgroundDisabled(int uid) {
21083        synchronized (this) {
21084            UidRecord uidRec = mActiveUids.get(uid);
21085            if (uidRec != null) {
21086                // This uid is actually running...  should it be considered background now?
21087                if (uidRec.idle) {
21088                    doStopUidLocked(uidRec.uid, uidRec);
21089                }
21090            } else {
21091                // This uid isn't actually running...  still send a report about it being "stopped".
21092                doStopUidLocked(uid, null);
21093            }
21094        }
21095    }
21096
21097    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21098        mServices.stopInBackgroundLocked(uid);
21099        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21100    }
21101
21102    final void trimApplications() {
21103        synchronized (this) {
21104            int i;
21105
21106            // First remove any unused application processes whose package
21107            // has been removed.
21108            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21109                final ProcessRecord app = mRemovedProcesses.get(i);
21110                if (app.activities.size() == 0
21111                        && app.curReceiver == null && app.services.size() == 0) {
21112                    Slog.i(
21113                        TAG, "Exiting empty application process "
21114                        + app.toShortString() + " ("
21115                        + (app.thread != null ? app.thread.asBinder() : null)
21116                        + ")\n");
21117                    if (app.pid > 0 && app.pid != MY_PID) {
21118                        app.kill("empty", false);
21119                    } else {
21120                        try {
21121                            app.thread.scheduleExit();
21122                        } catch (Exception e) {
21123                            // Ignore exceptions.
21124                        }
21125                    }
21126                    cleanUpApplicationRecordLocked(app, false, true, -1);
21127                    mRemovedProcesses.remove(i);
21128
21129                    if (app.persistent) {
21130                        addAppLocked(app.info, false, null /* ABI override */);
21131                    }
21132                }
21133            }
21134
21135            // Now update the oom adj for all processes.
21136            updateOomAdjLocked();
21137        }
21138    }
21139
21140    /** This method sends the specified signal to each of the persistent apps */
21141    public void signalPersistentProcesses(int sig) throws RemoteException {
21142        if (sig != Process.SIGNAL_USR1) {
21143            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21144        }
21145
21146        synchronized (this) {
21147            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21148                    != PackageManager.PERMISSION_GRANTED) {
21149                throw new SecurityException("Requires permission "
21150                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21151            }
21152
21153            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21154                ProcessRecord r = mLruProcesses.get(i);
21155                if (r.thread != null && r.persistent) {
21156                    Process.sendSignal(r.pid, sig);
21157                }
21158            }
21159        }
21160    }
21161
21162    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21163        if (proc == null || proc == mProfileProc) {
21164            proc = mProfileProc;
21165            profileType = mProfileType;
21166            clearProfilerLocked();
21167        }
21168        if (proc == null) {
21169            return;
21170        }
21171        try {
21172            proc.thread.profilerControl(false, null, profileType);
21173        } catch (RemoteException e) {
21174            throw new IllegalStateException("Process disappeared");
21175        }
21176    }
21177
21178    private void clearProfilerLocked() {
21179        if (mProfileFd != null) {
21180            try {
21181                mProfileFd.close();
21182            } catch (IOException e) {
21183            }
21184        }
21185        mProfileApp = null;
21186        mProfileProc = null;
21187        mProfileFile = null;
21188        mProfileType = 0;
21189        mAutoStopProfiler = false;
21190        mSamplingInterval = 0;
21191    }
21192
21193    public boolean profileControl(String process, int userId, boolean start,
21194            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21195
21196        try {
21197            synchronized (this) {
21198                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21199                // its own permission.
21200                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21201                        != PackageManager.PERMISSION_GRANTED) {
21202                    throw new SecurityException("Requires permission "
21203                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21204                }
21205
21206                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21207                    throw new IllegalArgumentException("null profile info or fd");
21208                }
21209
21210                ProcessRecord proc = null;
21211                if (process != null) {
21212                    proc = findProcessLocked(process, userId, "profileControl");
21213                }
21214
21215                if (start && (proc == null || proc.thread == null)) {
21216                    throw new IllegalArgumentException("Unknown process: " + process);
21217                }
21218
21219                if (start) {
21220                    stopProfilerLocked(null, 0);
21221                    setProfileApp(proc.info, proc.processName, profilerInfo);
21222                    mProfileProc = proc;
21223                    mProfileType = profileType;
21224                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21225                    try {
21226                        fd = fd.dup();
21227                    } catch (IOException e) {
21228                        fd = null;
21229                    }
21230                    profilerInfo.profileFd = fd;
21231                    proc.thread.profilerControl(start, profilerInfo, profileType);
21232                    fd = null;
21233                    mProfileFd = null;
21234                } else {
21235                    stopProfilerLocked(proc, profileType);
21236                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21237                        try {
21238                            profilerInfo.profileFd.close();
21239                        } catch (IOException e) {
21240                        }
21241                    }
21242                }
21243
21244                return true;
21245            }
21246        } catch (RemoteException e) {
21247            throw new IllegalStateException("Process disappeared");
21248        } finally {
21249            if (profilerInfo != null && profilerInfo.profileFd != null) {
21250                try {
21251                    profilerInfo.profileFd.close();
21252                } catch (IOException e) {
21253                }
21254            }
21255        }
21256    }
21257
21258    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21259        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21260                userId, true, ALLOW_FULL_ONLY, callName, null);
21261        ProcessRecord proc = null;
21262        try {
21263            int pid = Integer.parseInt(process);
21264            synchronized (mPidsSelfLocked) {
21265                proc = mPidsSelfLocked.get(pid);
21266            }
21267        } catch (NumberFormatException e) {
21268        }
21269
21270        if (proc == null) {
21271            ArrayMap<String, SparseArray<ProcessRecord>> all
21272                    = mProcessNames.getMap();
21273            SparseArray<ProcessRecord> procs = all.get(process);
21274            if (procs != null && procs.size() > 0) {
21275                proc = procs.valueAt(0);
21276                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21277                    for (int i=1; i<procs.size(); i++) {
21278                        ProcessRecord thisProc = procs.valueAt(i);
21279                        if (thisProc.userId == userId) {
21280                            proc = thisProc;
21281                            break;
21282                        }
21283                    }
21284                }
21285            }
21286        }
21287
21288        return proc;
21289    }
21290
21291    public boolean dumpHeap(String process, int userId, boolean managed,
21292            String path, ParcelFileDescriptor fd) throws RemoteException {
21293
21294        try {
21295            synchronized (this) {
21296                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21297                // its own permission (same as profileControl).
21298                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21299                        != PackageManager.PERMISSION_GRANTED) {
21300                    throw new SecurityException("Requires permission "
21301                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21302                }
21303
21304                if (fd == null) {
21305                    throw new IllegalArgumentException("null fd");
21306                }
21307
21308                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21309                if (proc == null || proc.thread == null) {
21310                    throw new IllegalArgumentException("Unknown process: " + process);
21311                }
21312
21313                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21314                if (!isDebuggable) {
21315                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21316                        throw new SecurityException("Process not debuggable: " + proc);
21317                    }
21318                }
21319
21320                proc.thread.dumpHeap(managed, path, fd);
21321                fd = null;
21322                return true;
21323            }
21324        } catch (RemoteException e) {
21325            throw new IllegalStateException("Process disappeared");
21326        } finally {
21327            if (fd != null) {
21328                try {
21329                    fd.close();
21330                } catch (IOException e) {
21331                }
21332            }
21333        }
21334    }
21335
21336    @Override
21337    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21338            String reportPackage) {
21339        if (processName != null) {
21340            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21341                    "setDumpHeapDebugLimit()");
21342        } else {
21343            synchronized (mPidsSelfLocked) {
21344                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21345                if (proc == null) {
21346                    throw new SecurityException("No process found for calling pid "
21347                            + Binder.getCallingPid());
21348                }
21349                if (!Build.IS_DEBUGGABLE
21350                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21351                    throw new SecurityException("Not running a debuggable build");
21352                }
21353                processName = proc.processName;
21354                uid = proc.uid;
21355                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21356                    throw new SecurityException("Package " + reportPackage + " is not running in "
21357                            + proc);
21358                }
21359            }
21360        }
21361        synchronized (this) {
21362            if (maxMemSize > 0) {
21363                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21364            } else {
21365                if (uid != 0) {
21366                    mMemWatchProcesses.remove(processName, uid);
21367                } else {
21368                    mMemWatchProcesses.getMap().remove(processName);
21369                }
21370            }
21371        }
21372    }
21373
21374    @Override
21375    public void dumpHeapFinished(String path) {
21376        synchronized (this) {
21377            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21378                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21379                        + " does not match last pid " + mMemWatchDumpPid);
21380                return;
21381            }
21382            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21383                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21384                        + " does not match last path " + mMemWatchDumpFile);
21385                return;
21386            }
21387            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21388            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21389        }
21390    }
21391
21392    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21393    public void monitor() {
21394        synchronized (this) { }
21395    }
21396
21397    void onCoreSettingsChange(Bundle settings) {
21398        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21399            ProcessRecord processRecord = mLruProcesses.get(i);
21400            try {
21401                if (processRecord.thread != null) {
21402                    processRecord.thread.setCoreSettings(settings);
21403                }
21404            } catch (RemoteException re) {
21405                /* ignore */
21406            }
21407        }
21408    }
21409
21410    // Multi-user methods
21411
21412    /**
21413     * Start user, if its not already running, but don't bring it to foreground.
21414     */
21415    @Override
21416    public boolean startUserInBackground(final int userId) {
21417        return mUserController.startUser(userId, /* foreground */ false);
21418    }
21419
21420    @Override
21421    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21422        return mUserController.unlockUser(userId, token, secret, listener);
21423    }
21424
21425    @Override
21426    public boolean switchUser(final int targetUserId) {
21427        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21428        UserInfo currentUserInfo;
21429        UserInfo targetUserInfo;
21430        synchronized (this) {
21431            int currentUserId = mUserController.getCurrentUserIdLocked();
21432            currentUserInfo = mUserController.getUserInfo(currentUserId);
21433            targetUserInfo = mUserController.getUserInfo(targetUserId);
21434            if (targetUserInfo == null) {
21435                Slog.w(TAG, "No user info for user #" + targetUserId);
21436                return false;
21437            }
21438            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21439                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21440                        + " when device is in demo mode");
21441                return false;
21442            }
21443            if (!targetUserInfo.supportsSwitchTo()) {
21444                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21445                return false;
21446            }
21447            if (targetUserInfo.isManagedProfile()) {
21448                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21449                return false;
21450            }
21451            mUserController.setTargetUserIdLocked(targetUserId);
21452        }
21453        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21454        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21455        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21456        return true;
21457    }
21458
21459    void scheduleStartProfilesLocked() {
21460        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21461            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21462                    DateUtils.SECOND_IN_MILLIS);
21463        }
21464    }
21465
21466    @Override
21467    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21468        return mUserController.stopUser(userId, force, callback);
21469    }
21470
21471    @Override
21472    public UserInfo getCurrentUser() {
21473        return mUserController.getCurrentUser();
21474    }
21475
21476    @Override
21477    public boolean isUserRunning(int userId, int flags) {
21478        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21479                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21480            String msg = "Permission Denial: isUserRunning() from pid="
21481                    + Binder.getCallingPid()
21482                    + ", uid=" + Binder.getCallingUid()
21483                    + " requires " + INTERACT_ACROSS_USERS;
21484            Slog.w(TAG, msg);
21485            throw new SecurityException(msg);
21486        }
21487        synchronized (this) {
21488            return mUserController.isUserRunningLocked(userId, flags);
21489        }
21490    }
21491
21492    @Override
21493    public int[] getRunningUserIds() {
21494        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21495                != PackageManager.PERMISSION_GRANTED) {
21496            String msg = "Permission Denial: isUserRunning() from pid="
21497                    + Binder.getCallingPid()
21498                    + ", uid=" + Binder.getCallingUid()
21499                    + " requires " + INTERACT_ACROSS_USERS;
21500            Slog.w(TAG, msg);
21501            throw new SecurityException(msg);
21502        }
21503        synchronized (this) {
21504            return mUserController.getStartedUserArrayLocked();
21505        }
21506    }
21507
21508    @Override
21509    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21510        mUserController.registerUserSwitchObserver(observer, name);
21511    }
21512
21513    @Override
21514    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21515        mUserController.unregisterUserSwitchObserver(observer);
21516    }
21517
21518    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21519        if (info == null) return null;
21520        ApplicationInfo newInfo = new ApplicationInfo(info);
21521        newInfo.initForUser(userId);
21522        return newInfo;
21523    }
21524
21525    public boolean isUserStopped(int userId) {
21526        synchronized (this) {
21527            return mUserController.getStartedUserStateLocked(userId) == null;
21528        }
21529    }
21530
21531    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21532        if (aInfo == null
21533                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21534            return aInfo;
21535        }
21536
21537        ActivityInfo info = new ActivityInfo(aInfo);
21538        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21539        return info;
21540    }
21541
21542    private boolean processSanityChecksLocked(ProcessRecord process) {
21543        if (process == null || process.thread == null) {
21544            return false;
21545        }
21546
21547        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21548        if (!isDebuggable) {
21549            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21550                return false;
21551            }
21552        }
21553
21554        return true;
21555    }
21556
21557    public boolean startBinderTracking() throws RemoteException {
21558        synchronized (this) {
21559            mBinderTransactionTrackingEnabled = true;
21560            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21561            // permission (same as profileControl).
21562            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21563                    != PackageManager.PERMISSION_GRANTED) {
21564                throw new SecurityException("Requires permission "
21565                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21566            }
21567
21568            for (int i = 0; i < mLruProcesses.size(); i++) {
21569                ProcessRecord process = mLruProcesses.get(i);
21570                if (!processSanityChecksLocked(process)) {
21571                    continue;
21572                }
21573                try {
21574                    process.thread.startBinderTracking();
21575                } catch (RemoteException e) {
21576                    Log.v(TAG, "Process disappared");
21577                }
21578            }
21579            return true;
21580        }
21581    }
21582
21583    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21584        try {
21585            synchronized (this) {
21586                mBinderTransactionTrackingEnabled = false;
21587                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21588                // permission (same as profileControl).
21589                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21590                        != PackageManager.PERMISSION_GRANTED) {
21591                    throw new SecurityException("Requires permission "
21592                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21593                }
21594
21595                if (fd == null) {
21596                    throw new IllegalArgumentException("null fd");
21597                }
21598
21599                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21600                pw.println("Binder transaction traces for all processes.\n");
21601                for (ProcessRecord process : mLruProcesses) {
21602                    if (!processSanityChecksLocked(process)) {
21603                        continue;
21604                    }
21605
21606                    pw.println("Traces for process: " + process.processName);
21607                    pw.flush();
21608                    try {
21609                        TransferPipe tp = new TransferPipe();
21610                        try {
21611                            process.thread.stopBinderTrackingAndDump(
21612                                    tp.getWriteFd().getFileDescriptor());
21613                            tp.go(fd.getFileDescriptor());
21614                        } finally {
21615                            tp.kill();
21616                        }
21617                    } catch (IOException e) {
21618                        pw.println("Failure while dumping IPC traces from " + process +
21619                                ".  Exception: " + e);
21620                        pw.flush();
21621                    } catch (RemoteException e) {
21622                        pw.println("Got a RemoteException while dumping IPC traces from " +
21623                                process + ".  Exception: " + e);
21624                        pw.flush();
21625                    }
21626                }
21627                fd = null;
21628                return true;
21629            }
21630        } finally {
21631            if (fd != null) {
21632                try {
21633                    fd.close();
21634                } catch (IOException e) {
21635                }
21636            }
21637        }
21638    }
21639
21640    private final class LocalService extends ActivityManagerInternal {
21641        @Override
21642        public void onWakefulnessChanged(int wakefulness) {
21643            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21644        }
21645
21646        @Override
21647        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21648                String processName, String abiOverride, int uid, Runnable crashHandler) {
21649            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21650                    processName, abiOverride, uid, crashHandler);
21651        }
21652
21653        @Override
21654        public SleepToken acquireSleepToken(String tag) {
21655            Preconditions.checkNotNull(tag);
21656
21657            ComponentName requestedVrService = null;
21658            ComponentName callingVrActivity = null;
21659            int userId = -1;
21660            synchronized (ActivityManagerService.this) {
21661                if (mFocusedActivity != null) {
21662                    requestedVrService = mFocusedActivity.requestedVrComponent;
21663                    callingVrActivity = mFocusedActivity.info.getComponentName();
21664                    userId = mFocusedActivity.userId;
21665                }
21666            }
21667
21668            if (requestedVrService != null) {
21669                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21670            }
21671
21672            synchronized (ActivityManagerService.this) {
21673                SleepTokenImpl token = new SleepTokenImpl(tag);
21674                mSleepTokens.add(token);
21675                updateSleepIfNeededLocked();
21676                return token;
21677            }
21678        }
21679
21680        @Override
21681        public ComponentName getHomeActivityForUser(int userId) {
21682            synchronized (ActivityManagerService.this) {
21683                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21684                return homeActivity == null ? null : homeActivity.realActivity;
21685            }
21686        }
21687
21688        @Override
21689        public void onUserRemoved(int userId) {
21690            synchronized (ActivityManagerService.this) {
21691                ActivityManagerService.this.onUserStoppedLocked(userId);
21692            }
21693        }
21694
21695        @Override
21696        public void onLocalVoiceInteractionStarted(IBinder activity,
21697                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21698            synchronized (ActivityManagerService.this) {
21699                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21700                        voiceSession, voiceInteractor);
21701            }
21702        }
21703
21704        @Override
21705        public void notifyStartingWindowDrawn() {
21706            synchronized (ActivityManagerService.this) {
21707                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21708            }
21709        }
21710
21711        @Override
21712        public void notifyAppTransitionStarting(int reason) {
21713            synchronized (ActivityManagerService.this) {
21714                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21715            }
21716        }
21717
21718        @Override
21719        public void notifyAppTransitionFinished() {
21720            synchronized (ActivityManagerService.this) {
21721                mStackSupervisor.notifyAppTransitionDone();
21722            }
21723        }
21724
21725        @Override
21726        public void notifyAppTransitionCancelled() {
21727            synchronized (ActivityManagerService.this) {
21728                mStackSupervisor.notifyAppTransitionDone();
21729            }
21730        }
21731
21732        @Override
21733        public List<IBinder> getTopVisibleActivities() {
21734            synchronized (ActivityManagerService.this) {
21735                return mStackSupervisor.getTopVisibleActivities();
21736            }
21737        }
21738
21739        @Override
21740        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21741            synchronized (ActivityManagerService.this) {
21742                mStackSupervisor.setDockedStackMinimized(minimized);
21743            }
21744        }
21745
21746        @Override
21747        public void killForegroundAppsForUser(int userHandle) {
21748            synchronized (ActivityManagerService.this) {
21749                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21750                final int NP = mProcessNames.getMap().size();
21751                for (int ip = 0; ip < NP; ip++) {
21752                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21753                    final int NA = apps.size();
21754                    for (int ia = 0; ia < NA; ia++) {
21755                        final ProcessRecord app = apps.valueAt(ia);
21756                        if (app.persistent) {
21757                            // We don't kill persistent processes.
21758                            continue;
21759                        }
21760                        if (app.removed) {
21761                            procs.add(app);
21762                        } else if (app.userId == userHandle && app.foregroundActivities) {
21763                            app.removed = true;
21764                            procs.add(app);
21765                        }
21766                    }
21767                }
21768
21769                final int N = procs.size();
21770                for (int i = 0; i < N; i++) {
21771                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21772                }
21773            }
21774        }
21775
21776        @Override
21777        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21778            if (!(target instanceof PendingIntentRecord)) {
21779                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21780                return;
21781            }
21782            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21783        }
21784
21785        @Override
21786        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21787                int userId) {
21788            Preconditions.checkNotNull(values, "Configuration must not be null");
21789            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21790            synchronized (ActivityManagerService.this) {
21791                updateConfigurationLocked(values, null, false, true, userId,
21792                        false /* deferResume */);
21793            }
21794        }
21795
21796        @Override
21797        public int startActivityAsPackage(String packageName, int userId, Intent intent,
21798                Bundle bOptions) {
21799            Preconditions.checkNotNull(intent, "intent");
21800            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
21801
21802            // UID of the package on user userId.
21803            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21804            // packageUid may not be initialized.
21805            int packageUid = 0;
21806            try {
21807                packageUid = AppGlobals.getPackageManager().getPackageUid(
21808                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21809            } catch (RemoteException e) {
21810                // Shouldn't happen.
21811            }
21812
21813            synchronized (ActivityManagerService.this) {
21814                return startActivityInPackage(packageUid, packageName, intent, resolvedType,
21815                        /*resultTo*/ null, /*resultWho*/ null, /*requestCode*/ 0, /*startFlags*/ 0,
21816                        bOptions, userId, /*container*/ null, /*inTask*/ null);
21817            }
21818        }
21819    }
21820
21821    private final class SleepTokenImpl extends SleepToken {
21822        private final String mTag;
21823        private final long mAcquireTime;
21824
21825        public SleepTokenImpl(String tag) {
21826            mTag = tag;
21827            mAcquireTime = SystemClock.uptimeMillis();
21828        }
21829
21830        @Override
21831        public void release() {
21832            synchronized (ActivityManagerService.this) {
21833                if (mSleepTokens.remove(this)) {
21834                    updateSleepIfNeededLocked();
21835                }
21836            }
21837        }
21838
21839        @Override
21840        public String toString() {
21841            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21842        }
21843    }
21844
21845    /**
21846     * An implementation of IAppTask, that allows an app to manage its own tasks via
21847     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21848     * only the process that calls getAppTasks() can call the AppTask methods.
21849     */
21850    class AppTaskImpl extends IAppTask.Stub {
21851        private int mTaskId;
21852        private int mCallingUid;
21853
21854        public AppTaskImpl(int taskId, int callingUid) {
21855            mTaskId = taskId;
21856            mCallingUid = callingUid;
21857        }
21858
21859        private void checkCaller() {
21860            if (mCallingUid != Binder.getCallingUid()) {
21861                throw new SecurityException("Caller " + mCallingUid
21862                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21863            }
21864        }
21865
21866        @Override
21867        public void finishAndRemoveTask() {
21868            checkCaller();
21869
21870            synchronized (ActivityManagerService.this) {
21871                long origId = Binder.clearCallingIdentity();
21872                try {
21873                    // We remove the task from recents to preserve backwards
21874                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21875                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21876                    }
21877                } finally {
21878                    Binder.restoreCallingIdentity(origId);
21879                }
21880            }
21881        }
21882
21883        @Override
21884        public ActivityManager.RecentTaskInfo getTaskInfo() {
21885            checkCaller();
21886
21887            synchronized (ActivityManagerService.this) {
21888                long origId = Binder.clearCallingIdentity();
21889                try {
21890                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21891                    if (tr == null) {
21892                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21893                    }
21894                    return createRecentTaskInfoFromTaskRecord(tr);
21895                } finally {
21896                    Binder.restoreCallingIdentity(origId);
21897                }
21898            }
21899        }
21900
21901        @Override
21902        public void moveToFront() {
21903            checkCaller();
21904            // Will bring task to front if it already has a root activity.
21905            final long origId = Binder.clearCallingIdentity();
21906            try {
21907                synchronized (this) {
21908                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21909                }
21910            } finally {
21911                Binder.restoreCallingIdentity(origId);
21912            }
21913        }
21914
21915        @Override
21916        public int startActivity(IBinder whoThread, String callingPackage,
21917                Intent intent, String resolvedType, Bundle bOptions) {
21918            checkCaller();
21919
21920            int callingUser = UserHandle.getCallingUserId();
21921            TaskRecord tr;
21922            IApplicationThread appThread;
21923            synchronized (ActivityManagerService.this) {
21924                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21925                if (tr == null) {
21926                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21927                }
21928                appThread = ApplicationThreadNative.asInterface(whoThread);
21929                if (appThread == null) {
21930                    throw new IllegalArgumentException("Bad app thread " + appThread);
21931                }
21932            }
21933            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21934                    resolvedType, null, null, null, null, 0, 0, null, null,
21935                    null, bOptions, false, callingUser, null, tr);
21936        }
21937
21938        @Override
21939        public void setExcludeFromRecents(boolean exclude) {
21940            checkCaller();
21941
21942            synchronized (ActivityManagerService.this) {
21943                long origId = Binder.clearCallingIdentity();
21944                try {
21945                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21946                    if (tr == null) {
21947                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21948                    }
21949                    Intent intent = tr.getBaseIntent();
21950                    if (exclude) {
21951                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21952                    } else {
21953                        intent.setFlags(intent.getFlags()
21954                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21955                    }
21956                } finally {
21957                    Binder.restoreCallingIdentity(origId);
21958                }
21959            }
21960        }
21961    }
21962
21963    /**
21964     * Kill processes for the user with id userId and that depend on the package named packageName
21965     */
21966    @Override
21967    public void killPackageDependents(String packageName, int userId) {
21968        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21969        if (packageName == null) {
21970            throw new NullPointerException(
21971                    "Cannot kill the dependents of a package without its name.");
21972        }
21973
21974        long callingId = Binder.clearCallingIdentity();
21975        IPackageManager pm = AppGlobals.getPackageManager();
21976        int pkgUid = -1;
21977        try {
21978            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21979        } catch (RemoteException e) {
21980        }
21981        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21982            throw new IllegalArgumentException(
21983                    "Cannot kill dependents of non-existing package " + packageName);
21984        }
21985        try {
21986            synchronized(this) {
21987                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21988                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21989                        "dep: " + packageName);
21990            }
21991        } finally {
21992            Binder.restoreCallingIdentity(callingId);
21993        }
21994    }
21995}
21996