ActivityManagerService.java revision 1f0151220e8c3054e826d2c89056bb3aeaf6542e
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1517
1518    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1519    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1520    static final int FIRST_COMPAT_MODE_MSG = 300;
1521    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1522
1523    static ServiceThread sKillThread = null;
1524    static KillHandler sKillHandler = null;
1525
1526    CompatModeDialog mCompatModeDialog;
1527    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1528    long mLastMemUsageReportTime = 0;
1529
1530    /**
1531     * Flag whether the current user is a "monkey", i.e. whether
1532     * the UI is driven by a UI automation tool.
1533     */
1534    private boolean mUserIsMonkey;
1535
1536    /** Flag whether the device has a Recents UI */
1537    boolean mHasRecents;
1538
1539    /** The dimensions of the thumbnails in the Recents UI. */
1540    int mThumbnailWidth;
1541    int mThumbnailHeight;
1542    float mFullscreenThumbnailScale;
1543
1544    final ServiceThread mHandlerThread;
1545    final MainHandler mHandler;
1546    final UiHandler mUiHandler;
1547
1548    PackageManagerInternal mPackageManagerInt;
1549
1550    // VoiceInteraction session ID that changes for each new request except when
1551    // being called for multiwindow assist in a single session.
1552    private int mViSessionId = 1000;
1553
1554    final class KillHandler extends Handler {
1555        static final int KILL_PROCESS_GROUP_MSG = 4000;
1556
1557        public KillHandler(Looper looper) {
1558            super(looper, null, true);
1559        }
1560
1561        @Override
1562        public void handleMessage(Message msg) {
1563            switch (msg.what) {
1564                case KILL_PROCESS_GROUP_MSG:
1565                {
1566                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1567                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1568                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1569                }
1570                break;
1571
1572                default:
1573                    super.handleMessage(msg);
1574            }
1575        }
1576    }
1577
1578    final class UiHandler extends Handler {
1579        public UiHandler() {
1580            super(com.android.server.UiThread.get().getLooper(), null, true);
1581        }
1582
1583        @Override
1584        public void handleMessage(Message msg) {
1585            switch (msg.what) {
1586            case SHOW_ERROR_UI_MSG: {
1587                mAppErrors.handleShowAppErrorUi(msg);
1588                ensureBootCompleted();
1589            } break;
1590            case SHOW_NOT_RESPONDING_UI_MSG: {
1591                mAppErrors.handleShowAnrUi(msg);
1592                ensureBootCompleted();
1593            } break;
1594            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1595                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1596                synchronized (ActivityManagerService.this) {
1597                    ProcessRecord proc = (ProcessRecord) data.get("app");
1598                    if (proc == null) {
1599                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1600                        break;
1601                    }
1602                    if (proc.crashDialog != null) {
1603                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1604                        return;
1605                    }
1606                    AppErrorResult res = (AppErrorResult) data.get("result");
1607                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1608                        Dialog d = new StrictModeViolationDialog(mContext,
1609                                ActivityManagerService.this, res, proc);
1610                        d.show();
1611                        proc.crashDialog = d;
1612                    } else {
1613                        // The device is asleep, so just pretend that the user
1614                        // saw a crash dialog and hit "force quit".
1615                        res.set(0);
1616                    }
1617                }
1618                ensureBootCompleted();
1619            } break;
1620            case SHOW_FACTORY_ERROR_UI_MSG: {
1621                Dialog d = new FactoryErrorDialog(
1622                    mContext, msg.getData().getCharSequence("msg"));
1623                d.show();
1624                ensureBootCompleted();
1625            } break;
1626            case WAIT_FOR_DEBUGGER_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ProcessRecord app = (ProcessRecord)msg.obj;
1629                    if (msg.arg1 != 0) {
1630                        if (!app.waitedForDebugger) {
1631                            Dialog d = new AppWaitingForDebuggerDialog(
1632                                    ActivityManagerService.this,
1633                                    mContext, app);
1634                            app.waitDialog = d;
1635                            app.waitedForDebugger = true;
1636                            d.show();
1637                        }
1638                    } else {
1639                        if (app.waitDialog != null) {
1640                            app.waitDialog.dismiss();
1641                            app.waitDialog = null;
1642                        }
1643                    }
1644                }
1645            } break;
1646            case SHOW_UID_ERROR_UI_MSG: {
1647                if (mShowDialogs) {
1648                    AlertDialog d = new BaseErrorDialog(mContext);
1649                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1650                    d.setCancelable(false);
1651                    d.setTitle(mContext.getText(R.string.android_system_label));
1652                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1653                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1654                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1655                    d.show();
1656                }
1657            } break;
1658            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1659                if (mShowDialogs) {
1660                    AlertDialog d = new BaseErrorDialog(mContext);
1661                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1662                    d.setCancelable(false);
1663                    d.setTitle(mContext.getText(R.string.android_system_label));
1664                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1665                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1666                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1667                    d.show();
1668                }
1669            } break;
1670            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1671                synchronized (ActivityManagerService.this) {
1672                    ActivityRecord ar = (ActivityRecord) msg.obj;
1673                    if (mCompatModeDialog != null) {
1674                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1675                                ar.info.applicationInfo.packageName)) {
1676                            return;
1677                        }
1678                        mCompatModeDialog.dismiss();
1679                        mCompatModeDialog = null;
1680                    }
1681                    if (ar != null && false) {
1682                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1683                                ar.packageName)) {
1684                            int mode = mCompatModePackages.computeCompatModeLocked(
1685                                    ar.info.applicationInfo);
1686                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1687                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1688                                mCompatModeDialog = new CompatModeDialog(
1689                                        ActivityManagerService.this, mContext,
1690                                        ar.info.applicationInfo);
1691                                mCompatModeDialog.show();
1692                            }
1693                        }
1694                    }
1695                }
1696                break;
1697            }
1698            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1701                    if (mUnsupportedDisplaySizeDialog != null) {
1702                        mUnsupportedDisplaySizeDialog.dismiss();
1703                        mUnsupportedDisplaySizeDialog = null;
1704                    }
1705                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1706                            ar.packageName)) {
1707                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1708                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1709                        mUnsupportedDisplaySizeDialog.show();
1710                    }
1711                }
1712                break;
1713            }
1714            case START_USER_SWITCH_UI_MSG: {
1715                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1716                break;
1717            }
1718            case DISMISS_DIALOG_UI_MSG: {
1719                final Dialog d = (Dialog) msg.obj;
1720                d.dismiss();
1721                break;
1722            }
1723            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1724                dispatchProcessesChanged();
1725                break;
1726            }
1727            case DISPATCH_PROCESS_DIED_UI_MSG: {
1728                final int pid = msg.arg1;
1729                final int uid = msg.arg2;
1730                dispatchProcessDied(pid, uid);
1731                break;
1732            }
1733            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1734                dispatchUidsChanged();
1735            } break;
1736            }
1737        }
1738    }
1739
1740    final class MainHandler extends Handler {
1741        public MainHandler(Looper looper) {
1742            super(looper, null, true);
1743        }
1744
1745        @Override
1746        public void handleMessage(Message msg) {
1747            switch (msg.what) {
1748            case UPDATE_CONFIGURATION_MSG: {
1749                final ContentResolver resolver = mContext.getContentResolver();
1750                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1751                        msg.arg1);
1752            } break;
1753            case GC_BACKGROUND_PROCESSES_MSG: {
1754                synchronized (ActivityManagerService.this) {
1755                    performAppGcsIfAppropriateLocked();
1756                }
1757            } break;
1758            case SERVICE_TIMEOUT_MSG: {
1759                if (mDidDexOpt) {
1760                    mDidDexOpt = false;
1761                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1762                    nmsg.obj = msg.obj;
1763                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1764                    return;
1765                }
1766                mServices.serviceTimeout((ProcessRecord)msg.obj);
1767            } break;
1768            case UPDATE_TIME_ZONE: {
1769                synchronized (ActivityManagerService.this) {
1770                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1771                        ProcessRecord r = mLruProcesses.get(i);
1772                        if (r.thread != null) {
1773                            try {
1774                                r.thread.updateTimeZone();
1775                            } catch (RemoteException ex) {
1776                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1777                            }
1778                        }
1779                    }
1780                }
1781            } break;
1782            case CLEAR_DNS_CACHE_MSG: {
1783                synchronized (ActivityManagerService.this) {
1784                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1785                        ProcessRecord r = mLruProcesses.get(i);
1786                        if (r.thread != null) {
1787                            try {
1788                                r.thread.clearDnsCache();
1789                            } catch (RemoteException ex) {
1790                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1791                            }
1792                        }
1793                    }
1794                }
1795            } break;
1796            case UPDATE_HTTP_PROXY_MSG: {
1797                ProxyInfo proxy = (ProxyInfo)msg.obj;
1798                String host = "";
1799                String port = "";
1800                String exclList = "";
1801                Uri pacFileUrl = Uri.EMPTY;
1802                if (proxy != null) {
1803                    host = proxy.getHost();
1804                    port = Integer.toString(proxy.getPort());
1805                    exclList = proxy.getExclusionListAsString();
1806                    pacFileUrl = proxy.getPacFileUrl();
1807                }
1808                synchronized (ActivityManagerService.this) {
1809                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1810                        ProcessRecord r = mLruProcesses.get(i);
1811                        if (r.thread != null) {
1812                            try {
1813                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1814                            } catch (RemoteException ex) {
1815                                Slog.w(TAG, "Failed to update http proxy for: " +
1816                                        r.info.processName);
1817                            }
1818                        }
1819                    }
1820                }
1821            } break;
1822            case PROC_START_TIMEOUT_MSG: {
1823                if (mDidDexOpt) {
1824                    mDidDexOpt = false;
1825                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1826                    nmsg.obj = msg.obj;
1827                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1828                    return;
1829                }
1830                ProcessRecord app = (ProcessRecord)msg.obj;
1831                synchronized (ActivityManagerService.this) {
1832                    processStartTimedOutLocked(app);
1833                }
1834            } break;
1835            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1836                ProcessRecord app = (ProcessRecord)msg.obj;
1837                synchronized (ActivityManagerService.this) {
1838                    processContentProviderPublishTimedOutLocked(app);
1839                }
1840            } break;
1841            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1842                synchronized (ActivityManagerService.this) {
1843                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1844                }
1845            } break;
1846            case KILL_APPLICATION_MSG: {
1847                synchronized (ActivityManagerService.this) {
1848                    int appid = msg.arg1;
1849                    boolean restart = (msg.arg2 == 1);
1850                    Bundle bundle = (Bundle)msg.obj;
1851                    String pkg = bundle.getString("pkg");
1852                    String reason = bundle.getString("reason");
1853                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1854                            false, UserHandle.USER_ALL, reason);
1855                }
1856            } break;
1857            case FINALIZE_PENDING_INTENT_MSG: {
1858                ((PendingIntentRecord)msg.obj).completeFinalize();
1859            } break;
1860            case POST_HEAVY_NOTIFICATION_MSG: {
1861                INotificationManager inm = NotificationManager.getService();
1862                if (inm == null) {
1863                    return;
1864                }
1865
1866                ActivityRecord root = (ActivityRecord)msg.obj;
1867                ProcessRecord process = root.app;
1868                if (process == null) {
1869                    return;
1870                }
1871
1872                try {
1873                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1874                    String text = mContext.getString(R.string.heavy_weight_notification,
1875                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1876                    Notification notification = new Notification.Builder(context)
1877                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1878                            .setWhen(0)
1879                            .setOngoing(true)
1880                            .setTicker(text)
1881                            .setColor(mContext.getColor(
1882                                    com.android.internal.R.color.system_notification_accent_color))
1883                            .setContentTitle(text)
1884                            .setContentText(
1885                                    mContext.getText(R.string.heavy_weight_notification_detail))
1886                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1887                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1888                                    new UserHandle(root.userId)))
1889                            .build();
1890                    try {
1891                        int[] outId = new int[1];
1892                        inm.enqueueNotificationWithTag("android", "android", null,
1893                                R.string.heavy_weight_notification,
1894                                notification, outId, root.userId);
1895                    } catch (RuntimeException e) {
1896                        Slog.w(ActivityManagerService.TAG,
1897                                "Error showing notification for heavy-weight app", e);
1898                    } catch (RemoteException e) {
1899                    }
1900                } catch (NameNotFoundException e) {
1901                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1902                }
1903            } break;
1904            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1905                INotificationManager inm = NotificationManager.getService();
1906                if (inm == null) {
1907                    return;
1908                }
1909                try {
1910                    inm.cancelNotificationWithTag("android", null,
1911                            R.string.heavy_weight_notification,  msg.arg1);
1912                } catch (RuntimeException e) {
1913                    Slog.w(ActivityManagerService.TAG,
1914                            "Error canceling notification for service", e);
1915                } catch (RemoteException e) {
1916                }
1917            } break;
1918            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1919                synchronized (ActivityManagerService.this) {
1920                    checkExcessivePowerUsageLocked(true);
1921                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1922                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1923                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1924                }
1925            } break;
1926            case REPORT_MEM_USAGE_MSG: {
1927                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1928                Thread thread = new Thread() {
1929                    @Override public void run() {
1930                        reportMemUsage(memInfos);
1931                    }
1932                };
1933                thread.start();
1934                break;
1935            }
1936            case REPORT_USER_SWITCH_MSG: {
1937                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1938                break;
1939            }
1940            case CONTINUE_USER_SWITCH_MSG: {
1941                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1942                break;
1943            }
1944            case USER_SWITCH_TIMEOUT_MSG: {
1945                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1946                break;
1947            }
1948            case IMMERSIVE_MODE_LOCK_MSG: {
1949                final boolean nextState = (msg.arg1 != 0);
1950                if (mUpdateLock.isHeld() != nextState) {
1951                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1952                            "Applying new update lock state '" + nextState
1953                            + "' for " + (ActivityRecord)msg.obj);
1954                    if (nextState) {
1955                        mUpdateLock.acquire();
1956                    } else {
1957                        mUpdateLock.release();
1958                    }
1959                }
1960                break;
1961            }
1962            case PERSIST_URI_GRANTS_MSG: {
1963                writeGrantedUriPermissions();
1964                break;
1965            }
1966            case REQUEST_ALL_PSS_MSG: {
1967                synchronized (ActivityManagerService.this) {
1968                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1969                }
1970                break;
1971            }
1972            case START_PROFILES_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    mUserController.startProfilesLocked();
1975                }
1976                break;
1977            }
1978            case UPDATE_TIME: {
1979                synchronized (ActivityManagerService.this) {
1980                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1981                        ProcessRecord r = mLruProcesses.get(i);
1982                        if (r.thread != null) {
1983                            try {
1984                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1985                            } catch (RemoteException ex) {
1986                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1987                            }
1988                        }
1989                    }
1990                }
1991                break;
1992            }
1993            case SYSTEM_USER_START_MSG: {
1994                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1995                        Integer.toString(msg.arg1), msg.arg1);
1996                mSystemServiceManager.startUser(msg.arg1);
1997                break;
1998            }
1999            case SYSTEM_USER_UNLOCK_MSG: {
2000                final int userId = msg.arg1;
2001                mSystemServiceManager.unlockUser(userId);
2002                synchronized (ActivityManagerService.this) {
2003                    mRecentTasks.loadUserRecentsLocked(userId);
2004                }
2005                if (userId == UserHandle.USER_SYSTEM) {
2006                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2007                }
2008                installEncryptionUnawareProviders(userId);
2009                mUserController.finishUserUnlocked((UserState) msg.obj);
2010                break;
2011            }
2012            case SYSTEM_USER_CURRENT_MSG: {
2013                mBatteryStatsService.noteEvent(
2014                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2015                        Integer.toString(msg.arg2), msg.arg2);
2016                mBatteryStatsService.noteEvent(
2017                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2018                        Integer.toString(msg.arg1), msg.arg1);
2019                mSystemServiceManager.switchUser(msg.arg1);
2020                break;
2021            }
2022            case ENTER_ANIMATION_COMPLETE_MSG: {
2023                synchronized (ActivityManagerService.this) {
2024                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2025                    if (r != null && r.app != null && r.app.thread != null) {
2026                        try {
2027                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2028                        } catch (RemoteException e) {
2029                        }
2030                    }
2031                }
2032                break;
2033            }
2034            case FINISH_BOOTING_MSG: {
2035                if (msg.arg1 != 0) {
2036                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2037                    finishBooting();
2038                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2039                }
2040                if (msg.arg2 != 0) {
2041                    enableScreenAfterBoot();
2042                }
2043                break;
2044            }
2045            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2046                try {
2047                    Locale l = (Locale) msg.obj;
2048                    IBinder service = ServiceManager.getService("mount");
2049                    IMountService mountService = IMountService.Stub.asInterface(service);
2050                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2051                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2052                } catch (RemoteException e) {
2053                    Log.e(TAG, "Error storing locale for decryption UI", e);
2054                }
2055                break;
2056            }
2057            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2058                synchronized (ActivityManagerService.this) {
2059                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2060                        try {
2061                            // Make a one-way callback to the listener
2062                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2063                        } catch (RemoteException e){
2064                            // Handled by the RemoteCallbackList
2065                        }
2066                    }
2067                    mTaskStackListeners.finishBroadcast();
2068                }
2069                break;
2070            }
2071            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2072                synchronized (ActivityManagerService.this) {
2073                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2074                        try {
2075                            // Make a one-way callback to the listener
2076                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2077                        } catch (RemoteException e){
2078                            // Handled by the RemoteCallbackList
2079                        }
2080                    }
2081                    mTaskStackListeners.finishBroadcast();
2082                }
2083                break;
2084            }
2085            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2086                synchronized (ActivityManagerService.this) {
2087                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2088                        try {
2089                            // Make a one-way callback to the listener
2090                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2091                        } catch (RemoteException e){
2092                            // Handled by the RemoteCallbackList
2093                        }
2094                    }
2095                    mTaskStackListeners.finishBroadcast();
2096                }
2097                break;
2098            }
2099            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2100                synchronized (ActivityManagerService.this) {
2101                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2102                        try {
2103                            // Make a one-way callback to the listener
2104                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2105                        } catch (RemoteException e){
2106                            // Handled by the RemoteCallbackList
2107                        }
2108                    }
2109                    mTaskStackListeners.finishBroadcast();
2110                }
2111                break;
2112            }
2113            case NOTIFY_FORCED_RESIZABLE_MSG: {
2114                synchronized (ActivityManagerService.this) {
2115                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2116                        try {
2117                            // Make a one-way callback to the listener
2118                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2119                                    (String) msg.obj, msg.arg1);
2120                        } catch (RemoteException e){
2121                            // Handled by the RemoteCallbackList
2122                        }
2123                    }
2124                    mTaskStackListeners.finishBroadcast();
2125                }
2126                break;
2127            }
2128                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2129                    synchronized (ActivityManagerService.this) {
2130                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2131                            try {
2132                                // Make a one-way callback to the listener
2133                                mTaskStackListeners.getBroadcastItem(i)
2134                                        .onActivityDismissingDockedStack();
2135                            } catch (RemoteException e){
2136                                // Handled by the RemoteCallbackList
2137                            }
2138                        }
2139                        mTaskStackListeners.finishBroadcast();
2140                    }
2141                    break;
2142                }
2143            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2144                final int uid = msg.arg1;
2145                final byte[] firstPacket = (byte[]) msg.obj;
2146
2147                synchronized (mPidsSelfLocked) {
2148                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2149                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2150                        if (p.uid == uid) {
2151                            try {
2152                                p.thread.notifyCleartextNetwork(firstPacket);
2153                            } catch (RemoteException ignored) {
2154                            }
2155                        }
2156                    }
2157                }
2158                break;
2159            }
2160            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2161                final String procName;
2162                final int uid;
2163                final long memLimit;
2164                final String reportPackage;
2165                synchronized (ActivityManagerService.this) {
2166                    procName = mMemWatchDumpProcName;
2167                    uid = mMemWatchDumpUid;
2168                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2169                    if (val == null) {
2170                        val = mMemWatchProcesses.get(procName, 0);
2171                    }
2172                    if (val != null) {
2173                        memLimit = val.first;
2174                        reportPackage = val.second;
2175                    } else {
2176                        memLimit = 0;
2177                        reportPackage = null;
2178                    }
2179                }
2180                if (procName == null) {
2181                    return;
2182                }
2183
2184                if (DEBUG_PSS) Slog.d(TAG_PSS,
2185                        "Showing dump heap notification from " + procName + "/" + uid);
2186
2187                INotificationManager inm = NotificationManager.getService();
2188                if (inm == null) {
2189                    return;
2190                }
2191
2192                String text = mContext.getString(R.string.dump_heap_notification, procName);
2193
2194
2195                Intent deleteIntent = new Intent();
2196                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2197                Intent intent = new Intent();
2198                intent.setClassName("android", DumpHeapActivity.class.getName());
2199                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2200                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2201                if (reportPackage != null) {
2202                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2203                }
2204                int userId = UserHandle.getUserId(uid);
2205                Notification notification = new Notification.Builder(mContext)
2206                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2207                        .setWhen(0)
2208                        .setOngoing(true)
2209                        .setAutoCancel(true)
2210                        .setTicker(text)
2211                        .setColor(mContext.getColor(
2212                                com.android.internal.R.color.system_notification_accent_color))
2213                        .setContentTitle(text)
2214                        .setContentText(
2215                                mContext.getText(R.string.dump_heap_notification_detail))
2216                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2217                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2218                                new UserHandle(userId)))
2219                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2220                                deleteIntent, 0, UserHandle.SYSTEM))
2221                        .build();
2222
2223                try {
2224                    int[] outId = new int[1];
2225                    inm.enqueueNotificationWithTag("android", "android", null,
2226                            R.string.dump_heap_notification,
2227                            notification, outId, userId);
2228                } catch (RuntimeException e) {
2229                    Slog.w(ActivityManagerService.TAG,
2230                            "Error showing notification for dump heap", e);
2231                } catch (RemoteException e) {
2232                }
2233            } break;
2234            case DELETE_DUMPHEAP_MSG: {
2235                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2236                        DumpHeapActivity.JAVA_URI,
2237                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2238                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2239                        UserHandle.myUserId());
2240                synchronized (ActivityManagerService.this) {
2241                    mMemWatchDumpFile = null;
2242                    mMemWatchDumpProcName = null;
2243                    mMemWatchDumpPid = -1;
2244                    mMemWatchDumpUid = -1;
2245                }
2246            } break;
2247            case FOREGROUND_PROFILE_CHANGED_MSG: {
2248                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2249            } break;
2250            case REPORT_TIME_TRACKER_MSG: {
2251                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2252                tracker.deliverResult(mContext);
2253            } break;
2254            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2255                mUserController.dispatchUserSwitchComplete(msg.arg1);
2256            } break;
2257            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2258                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2259                try {
2260                    connection.shutdown();
2261                } catch (RemoteException e) {
2262                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2263                }
2264                // Only a UiAutomation can set this flag and now that
2265                // it is finished we make sure it is reset to its default.
2266                mUserIsMonkey = false;
2267            } break;
2268            case APP_BOOST_DEACTIVATE_MSG: {
2269                synchronized(ActivityManagerService.this) {
2270                    if (mIsBoosted) {
2271                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2272                            nativeMigrateFromBoost();
2273                            mIsBoosted = false;
2274                            mBoostStartTime = 0;
2275                        } else {
2276                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2277                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2278                        }
2279                    }
2280                }
2281            } break;
2282            case IDLE_UIDS_MSG: {
2283                idleUids();
2284            } break;
2285            case LOG_STACK_STATE: {
2286                synchronized (ActivityManagerService.this) {
2287                    mStackSupervisor.logStackState();
2288                }
2289            } break;
2290            case VR_MODE_CHANGE_MSG: {
2291                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                boolean vrMode;
2294                ComponentName requestedPackage;
2295                ComponentName callingPackage;
2296                int userId;
2297                synchronized (ActivityManagerService.this) {
2298                    vrMode = r.requestedVrComponent != null;
2299                    requestedPackage = r.requestedVrComponent;
2300                    userId = r.userId;
2301                    callingPackage = r.info.getComponentName();
2302                    if (mInVrMode != vrMode) {
2303                        mInVrMode = vrMode;
2304                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2305                    }
2306                }
2307                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2308            } break;
2309            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2310                final ActivityRecord r = (ActivityRecord) msg.obj;
2311                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2312                if (needsVrMode) {
2313                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2314                            r.info.getComponentName(), false);
2315                }
2316            } break;
2317            }
2318        }
2319    };
2320
2321    static final int COLLECT_PSS_BG_MSG = 1;
2322
2323    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2324        @Override
2325        public void handleMessage(Message msg) {
2326            switch (msg.what) {
2327            case COLLECT_PSS_BG_MSG: {
2328                long start = SystemClock.uptimeMillis();
2329                MemInfoReader memInfo = null;
2330                synchronized (ActivityManagerService.this) {
2331                    if (mFullPssPending) {
2332                        mFullPssPending = false;
2333                        memInfo = new MemInfoReader();
2334                    }
2335                }
2336                if (memInfo != null) {
2337                    updateCpuStatsNow();
2338                    long nativeTotalPss = 0;
2339                    synchronized (mProcessCpuTracker) {
2340                        final int N = mProcessCpuTracker.countStats();
2341                        for (int j=0; j<N; j++) {
2342                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2343                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2344                                // This is definitely an application process; skip it.
2345                                continue;
2346                            }
2347                            synchronized (mPidsSelfLocked) {
2348                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2349                                    // This is one of our own processes; skip it.
2350                                    continue;
2351                                }
2352                            }
2353                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2354                        }
2355                    }
2356                    memInfo.readMemInfo();
2357                    synchronized (ActivityManagerService.this) {
2358                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2359                                + (SystemClock.uptimeMillis()-start) + "ms");
2360                        final long cachedKb = memInfo.getCachedSizeKb();
2361                        final long freeKb = memInfo.getFreeSizeKb();
2362                        final long zramKb = memInfo.getZramTotalSizeKb();
2363                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2364                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2365                                kernelKb*1024, nativeTotalPss*1024);
2366                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2367                                nativeTotalPss);
2368                    }
2369                }
2370
2371                int num = 0;
2372                long[] tmp = new long[2];
2373                do {
2374                    ProcessRecord proc;
2375                    int procState;
2376                    int pid;
2377                    long lastPssTime;
2378                    synchronized (ActivityManagerService.this) {
2379                        if (mPendingPssProcesses.size() <= 0) {
2380                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2381                                    "Collected PSS of " + num + " processes in "
2382                                    + (SystemClock.uptimeMillis() - start) + "ms");
2383                            mPendingPssProcesses.clear();
2384                            return;
2385                        }
2386                        proc = mPendingPssProcesses.remove(0);
2387                        procState = proc.pssProcState;
2388                        lastPssTime = proc.lastPssTime;
2389                        if (proc.thread != null && procState == proc.setProcState
2390                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2391                                        < SystemClock.uptimeMillis()) {
2392                            pid = proc.pid;
2393                        } else {
2394                            proc = null;
2395                            pid = 0;
2396                        }
2397                    }
2398                    if (proc != null) {
2399                        long pss = Debug.getPss(pid, tmp, null);
2400                        synchronized (ActivityManagerService.this) {
2401                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2402                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2403                                num++;
2404                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2405                                        SystemClock.uptimeMillis());
2406                            }
2407                        }
2408                    }
2409                } while (true);
2410            }
2411            }
2412        }
2413    };
2414
2415    public void setSystemProcess() {
2416        try {
2417            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2418            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2419            ServiceManager.addService("meminfo", new MemBinder(this));
2420            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2421            ServiceManager.addService("dbinfo", new DbBinder(this));
2422            if (MONITOR_CPU_USAGE) {
2423                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2424            }
2425            ServiceManager.addService("permission", new PermissionController(this));
2426            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2427
2428            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2429                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2430            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2431
2432            synchronized (this) {
2433                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2434                app.persistent = true;
2435                app.pid = MY_PID;
2436                app.maxAdj = ProcessList.SYSTEM_ADJ;
2437                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2438                synchronized (mPidsSelfLocked) {
2439                    mPidsSelfLocked.put(app.pid, app);
2440                }
2441                updateLruProcessLocked(app, false, null);
2442                updateOomAdjLocked();
2443            }
2444        } catch (PackageManager.NameNotFoundException e) {
2445            throw new RuntimeException(
2446                    "Unable to find android system package", e);
2447        }
2448    }
2449
2450    public void setWindowManager(WindowManagerService wm) {
2451        mWindowManager = wm;
2452        mStackSupervisor.setWindowManager(wm);
2453        mActivityStarter.setWindowManager(wm);
2454    }
2455
2456    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2457        mUsageStatsService = usageStatsManager;
2458    }
2459
2460    public void startObservingNativeCrashes() {
2461        final NativeCrashListener ncl = new NativeCrashListener(this);
2462        ncl.start();
2463    }
2464
2465    public IAppOpsService getAppOpsService() {
2466        return mAppOpsService;
2467    }
2468
2469    static class MemBinder extends Binder {
2470        ActivityManagerService mActivityManagerService;
2471        MemBinder(ActivityManagerService activityManagerService) {
2472            mActivityManagerService = activityManagerService;
2473        }
2474
2475        @Override
2476        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2477            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2478                    != PackageManager.PERMISSION_GRANTED) {
2479                pw.println("Permission Denial: can't dump meminfo from from pid="
2480                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2481                        + " without permission " + android.Manifest.permission.DUMP);
2482                return;
2483            }
2484
2485            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2486        }
2487    }
2488
2489    static class GraphicsBinder extends Binder {
2490        ActivityManagerService mActivityManagerService;
2491        GraphicsBinder(ActivityManagerService activityManagerService) {
2492            mActivityManagerService = activityManagerService;
2493        }
2494
2495        @Override
2496        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2497            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2498                    != PackageManager.PERMISSION_GRANTED) {
2499                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2500                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2501                        + " without permission " + android.Manifest.permission.DUMP);
2502                return;
2503            }
2504
2505            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2506        }
2507    }
2508
2509    static class DbBinder extends Binder {
2510        ActivityManagerService mActivityManagerService;
2511        DbBinder(ActivityManagerService activityManagerService) {
2512            mActivityManagerService = activityManagerService;
2513        }
2514
2515        @Override
2516        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2517            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2518                    != PackageManager.PERMISSION_GRANTED) {
2519                pw.println("Permission Denial: can't dump dbinfo from from pid="
2520                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2521                        + " without permission " + android.Manifest.permission.DUMP);
2522                return;
2523            }
2524
2525            mActivityManagerService.dumpDbInfo(fd, pw, args);
2526        }
2527    }
2528
2529    static class CpuBinder extends Binder {
2530        ActivityManagerService mActivityManagerService;
2531        CpuBinder(ActivityManagerService activityManagerService) {
2532            mActivityManagerService = activityManagerService;
2533        }
2534
2535        @Override
2536        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2537            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2538                    != PackageManager.PERMISSION_GRANTED) {
2539                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2540                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2541                        + " without permission " + android.Manifest.permission.DUMP);
2542                return;
2543            }
2544
2545            synchronized (mActivityManagerService.mProcessCpuTracker) {
2546                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2547                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2548                        SystemClock.uptimeMillis()));
2549            }
2550        }
2551    }
2552
2553    public static final class Lifecycle extends SystemService {
2554        private final ActivityManagerService mService;
2555
2556        public Lifecycle(Context context) {
2557            super(context);
2558            mService = new ActivityManagerService(context);
2559        }
2560
2561        @Override
2562        public void onStart() {
2563            mService.start();
2564        }
2565
2566        public ActivityManagerService getService() {
2567            return mService;
2568        }
2569    }
2570
2571    // Note: This method is invoked on the main thread but may need to attach various
2572    // handlers to other threads.  So take care to be explicit about the looper.
2573    public ActivityManagerService(Context systemContext) {
2574        mContext = systemContext;
2575        mFactoryTest = FactoryTest.getMode();
2576        mSystemThread = ActivityThread.currentActivityThread();
2577
2578        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2579
2580        mHandlerThread = new ServiceThread(TAG,
2581                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2582        mHandlerThread.start();
2583        mHandler = new MainHandler(mHandlerThread.getLooper());
2584        mUiHandler = new UiHandler();
2585
2586        /* static; one-time init here */
2587        if (sKillHandler == null) {
2588            sKillThread = new ServiceThread(TAG + ":kill",
2589                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2590            sKillThread.start();
2591            sKillHandler = new KillHandler(sKillThread.getLooper());
2592        }
2593
2594        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2595                "foreground", BROADCAST_FG_TIMEOUT, false);
2596        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2597                "background", BROADCAST_BG_TIMEOUT, true);
2598        mBroadcastQueues[0] = mFgBroadcastQueue;
2599        mBroadcastQueues[1] = mBgBroadcastQueue;
2600
2601        mServices = new ActiveServices(this);
2602        mProviderMap = new ProviderMap(this);
2603        mAppErrors = new AppErrors(mContext, this);
2604
2605        // TODO: Move creation of battery stats service outside of activity manager service.
2606        File dataDir = Environment.getDataDirectory();
2607        File systemDir = new File(dataDir, "system");
2608        systemDir.mkdirs();
2609        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2610        mBatteryStatsService.getActiveStatistics().readLocked();
2611        mBatteryStatsService.scheduleWriteToDisk();
2612        mOnBattery = DEBUG_POWER ? true
2613                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2614        mBatteryStatsService.getActiveStatistics().setCallback(this);
2615
2616        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2617
2618        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2619        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2620                new IAppOpsCallback.Stub() {
2621                    @Override public void opChanged(int op, int uid, String packageName) {
2622                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2623                            if (mAppOpsService.checkOperation(op, uid, packageName)
2624                                    != AppOpsManager.MODE_ALLOWED) {
2625                                runInBackgroundDisabled(uid);
2626                            }
2627                        }
2628                    }
2629                });
2630
2631        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2632
2633        mUserController = new UserController(this);
2634
2635        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2636            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2637
2638        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2639
2640        mConfiguration.setToDefaults();
2641        mConfiguration.setLocales(LocaleList.getDefault());
2642
2643        mConfigurationSeq = mConfiguration.seq = 1;
2644        mProcessCpuTracker.init();
2645
2646        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2647        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2648        mStackSupervisor = new ActivityStackSupervisor(this);
2649        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2650        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2651
2652        mProcessCpuThread = new Thread("CpuTracker") {
2653            @Override
2654            public void run() {
2655                while (true) {
2656                    try {
2657                        try {
2658                            synchronized(this) {
2659                                final long now = SystemClock.uptimeMillis();
2660                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2661                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2662                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2663                                //        + ", write delay=" + nextWriteDelay);
2664                                if (nextWriteDelay < nextCpuDelay) {
2665                                    nextCpuDelay = nextWriteDelay;
2666                                }
2667                                if (nextCpuDelay > 0) {
2668                                    mProcessCpuMutexFree.set(true);
2669                                    this.wait(nextCpuDelay);
2670                                }
2671                            }
2672                        } catch (InterruptedException e) {
2673                        }
2674                        updateCpuStatsNow();
2675                    } catch (Exception e) {
2676                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2677                    }
2678                }
2679            }
2680        };
2681
2682        Watchdog.getInstance().addMonitor(this);
2683        Watchdog.getInstance().addThread(mHandler);
2684    }
2685
2686    public void setSystemServiceManager(SystemServiceManager mgr) {
2687        mSystemServiceManager = mgr;
2688    }
2689
2690    public void setInstaller(Installer installer) {
2691        mInstaller = installer;
2692    }
2693
2694    private void start() {
2695        Process.removeAllProcessGroups();
2696        mProcessCpuThread.start();
2697
2698        mBatteryStatsService.publish(mContext);
2699        mAppOpsService.publish(mContext);
2700        Slog.d("AppOps", "AppOpsService published");
2701        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2702    }
2703
2704    void onUserStoppedLocked(int userId) {
2705        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2706    }
2707
2708    public void initPowerManagement() {
2709        mStackSupervisor.initPowerManagement();
2710        mBatteryStatsService.initPowerManagement();
2711        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2712        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2713        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2714        mVoiceWakeLock.setReferenceCounted(false);
2715    }
2716
2717    @Override
2718    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2719            throws RemoteException {
2720        if (code == SYSPROPS_TRANSACTION) {
2721            // We need to tell all apps about the system property change.
2722            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2723            synchronized(this) {
2724                final int NP = mProcessNames.getMap().size();
2725                for (int ip=0; ip<NP; ip++) {
2726                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2727                    final int NA = apps.size();
2728                    for (int ia=0; ia<NA; ia++) {
2729                        ProcessRecord app = apps.valueAt(ia);
2730                        if (app.thread != null) {
2731                            procs.add(app.thread.asBinder());
2732                        }
2733                    }
2734                }
2735            }
2736
2737            int N = procs.size();
2738            for (int i=0; i<N; i++) {
2739                Parcel data2 = Parcel.obtain();
2740                try {
2741                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2742                } catch (RemoteException e) {
2743                }
2744                data2.recycle();
2745            }
2746        }
2747        try {
2748            return super.onTransact(code, data, reply, flags);
2749        } catch (RuntimeException e) {
2750            // The activity manager only throws security exceptions, so let's
2751            // log all others.
2752            if (!(e instanceof SecurityException)) {
2753                Slog.wtf(TAG, "Activity Manager Crash", e);
2754            }
2755            throw e;
2756        }
2757    }
2758
2759    void updateCpuStats() {
2760        final long now = SystemClock.uptimeMillis();
2761        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2762            return;
2763        }
2764        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2765            synchronized (mProcessCpuThread) {
2766                mProcessCpuThread.notify();
2767            }
2768        }
2769    }
2770
2771    void updateCpuStatsNow() {
2772        synchronized (mProcessCpuTracker) {
2773            mProcessCpuMutexFree.set(false);
2774            final long now = SystemClock.uptimeMillis();
2775            boolean haveNewCpuStats = false;
2776
2777            if (MONITOR_CPU_USAGE &&
2778                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2779                mLastCpuTime.set(now);
2780                mProcessCpuTracker.update();
2781                if (mProcessCpuTracker.hasGoodLastStats()) {
2782                    haveNewCpuStats = true;
2783                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2784                    //Slog.i(TAG, "Total CPU usage: "
2785                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2786
2787                    // Slog the cpu usage if the property is set.
2788                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2789                        int user = mProcessCpuTracker.getLastUserTime();
2790                        int system = mProcessCpuTracker.getLastSystemTime();
2791                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2792                        int irq = mProcessCpuTracker.getLastIrqTime();
2793                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2794                        int idle = mProcessCpuTracker.getLastIdleTime();
2795
2796                        int total = user + system + iowait + irq + softIrq + idle;
2797                        if (total == 0) total = 1;
2798
2799                        EventLog.writeEvent(EventLogTags.CPU,
2800                                ((user+system+iowait+irq+softIrq) * 100) / total,
2801                                (user * 100) / total,
2802                                (system * 100) / total,
2803                                (iowait * 100) / total,
2804                                (irq * 100) / total,
2805                                (softIrq * 100) / total);
2806                    }
2807                }
2808            }
2809
2810            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2811            synchronized(bstats) {
2812                synchronized(mPidsSelfLocked) {
2813                    if (haveNewCpuStats) {
2814                        if (bstats.startAddingCpuLocked()) {
2815                            int totalUTime = 0;
2816                            int totalSTime = 0;
2817                            final int N = mProcessCpuTracker.countStats();
2818                            for (int i=0; i<N; i++) {
2819                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2820                                if (!st.working) {
2821                                    continue;
2822                                }
2823                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2824                                totalUTime += st.rel_utime;
2825                                totalSTime += st.rel_stime;
2826                                if (pr != null) {
2827                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2828                                    if (ps == null || !ps.isActive()) {
2829                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2830                                                pr.info.uid, pr.processName);
2831                                    }
2832                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2833                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2834                                } else {
2835                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2836                                    if (ps == null || !ps.isActive()) {
2837                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2838                                                bstats.mapUid(st.uid), st.name);
2839                                    }
2840                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2841                                }
2842                            }
2843                            final int userTime = mProcessCpuTracker.getLastUserTime();
2844                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2845                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2846                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2847                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2848                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2849                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2850                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2851                        }
2852                    }
2853                }
2854
2855                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2856                    mLastWriteTime = now;
2857                    mBatteryStatsService.scheduleWriteToDisk();
2858                }
2859            }
2860        }
2861    }
2862
2863    @Override
2864    public void batteryNeedsCpuUpdate() {
2865        updateCpuStatsNow();
2866    }
2867
2868    @Override
2869    public void batteryPowerChanged(boolean onBattery) {
2870        // When plugging in, update the CPU stats first before changing
2871        // the plug state.
2872        updateCpuStatsNow();
2873        synchronized (this) {
2874            synchronized(mPidsSelfLocked) {
2875                mOnBattery = DEBUG_POWER ? true : onBattery;
2876            }
2877        }
2878    }
2879
2880    @Override
2881    public void batterySendBroadcast(Intent intent) {
2882        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2883                AppOpsManager.OP_NONE, null, false, false,
2884                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2885    }
2886
2887    /**
2888     * Initialize the application bind args. These are passed to each
2889     * process when the bindApplication() IPC is sent to the process. They're
2890     * lazily setup to make sure the services are running when they're asked for.
2891     */
2892    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2893        if (mAppBindArgs == null) {
2894            mAppBindArgs = new HashMap<>();
2895
2896            // Isolated processes won't get this optimization, so that we don't
2897            // violate the rules about which services they have access to.
2898            if (!isolated) {
2899                // Setup the application init args
2900                mAppBindArgs.put("package", ServiceManager.getService("package"));
2901                mAppBindArgs.put("window", ServiceManager.getService("window"));
2902                mAppBindArgs.put(Context.ALARM_SERVICE,
2903                        ServiceManager.getService(Context.ALARM_SERVICE));
2904            }
2905        }
2906        return mAppBindArgs;
2907    }
2908
2909    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2910        if (r == null || mFocusedActivity == r) {
2911            return false;
2912        }
2913
2914        if (!r.isFocusable()) {
2915            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2916            return false;
2917        }
2918
2919        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2920
2921        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2922        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2923                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2924        mDoingSetFocusedActivity = true;
2925
2926        final ActivityRecord last = mFocusedActivity;
2927        mFocusedActivity = r;
2928        if (r.task.isApplicationTask()) {
2929            if (mCurAppTimeTracker != r.appTimeTracker) {
2930                // We are switching app tracking.  Complete the current one.
2931                if (mCurAppTimeTracker != null) {
2932                    mCurAppTimeTracker.stop();
2933                    mHandler.obtainMessage(
2934                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2935                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2936                    mCurAppTimeTracker = null;
2937                }
2938                if (r.appTimeTracker != null) {
2939                    mCurAppTimeTracker = r.appTimeTracker;
2940                    startTimeTrackingFocusedActivityLocked();
2941                }
2942            } else {
2943                startTimeTrackingFocusedActivityLocked();
2944            }
2945        } else {
2946            r.appTimeTracker = null;
2947        }
2948        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2949        // TODO: Probably not, because we don't want to resume voice on switching
2950        // back to this activity
2951        if (r.task.voiceInteractor != null) {
2952            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2953        } else {
2954            finishRunningVoiceLocked();
2955            IVoiceInteractionSession session;
2956            if (last != null && ((session = last.task.voiceSession) != null
2957                    || (session = last.voiceSession) != null)) {
2958                // We had been in a voice interaction session, but now focused has
2959                // move to something different.  Just finish the session, we can't
2960                // return to it and retain the proper state and synchronization with
2961                // the voice interaction service.
2962                finishVoiceTask(session);
2963            }
2964        }
2965        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2966            mWindowManager.setFocusedApp(r.appToken, true);
2967        }
2968        applyUpdateLockStateLocked(r);
2969        applyUpdateVrModeLocked(r);
2970        if (mFocusedActivity.userId != mLastFocusedUserId) {
2971            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2972            mHandler.obtainMessage(
2973                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2974            mLastFocusedUserId = mFocusedActivity.userId;
2975        }
2976
2977        // Log a warning if the focused app is changed during the process. This could
2978        // indicate a problem of the focus setting logic!
2979        if (mFocusedActivity != r) Slog.w(TAG,
2980                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2981        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2982
2983        EventLogTags.writeAmFocusedActivity(
2984                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2985                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2986                reason);
2987        return true;
2988    }
2989
2990    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2991        if (mFocusedActivity != goingAway) {
2992            return;
2993        }
2994
2995        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2996        if (focusedStack != null) {
2997            final ActivityRecord top = focusedStack.topActivity();
2998            if (top != null && top.userId != mLastFocusedUserId) {
2999                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3000                mHandler.sendMessage(
3001                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3002                mLastFocusedUserId = top.userId;
3003            }
3004        }
3005
3006        // Try to move focus to another activity if possible.
3007        if (setFocusedActivityLocked(
3008                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3009            return;
3010        }
3011
3012        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3013                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3014        mFocusedActivity = null;
3015        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3016    }
3017
3018    @Override
3019    public void setFocusedStack(int stackId) {
3020        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3021        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3022        final long callingId = Binder.clearCallingIdentity();
3023        try {
3024            synchronized (this) {
3025                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3026                if (stack == null) {
3027                    return;
3028                }
3029                final ActivityRecord r = stack.topRunningActivityLocked();
3030                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3031                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3032                }
3033            }
3034        } finally {
3035            Binder.restoreCallingIdentity(callingId);
3036        }
3037    }
3038
3039    @Override
3040    public void setFocusedTask(int taskId) {
3041        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3042        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3043        final long callingId = Binder.clearCallingIdentity();
3044        try {
3045            synchronized (this) {
3046                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3047                if (task == null) {
3048                    return;
3049                }
3050                final ActivityRecord r = task.topRunningActivityLocked();
3051                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3052                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3053                }
3054            }
3055        } finally {
3056            Binder.restoreCallingIdentity(callingId);
3057        }
3058    }
3059
3060    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3061    @Override
3062    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3064        synchronized (this) {
3065            if (listener != null) {
3066                mTaskStackListeners.register(listener);
3067            }
3068        }
3069    }
3070
3071    @Override
3072    public void notifyActivityDrawn(IBinder token) {
3073        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3074        synchronized (this) {
3075            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3076            if (r != null) {
3077                r.task.stack.notifyActivityDrawnLocked(r);
3078            }
3079        }
3080    }
3081
3082    final void applyUpdateLockStateLocked(ActivityRecord r) {
3083        // Modifications to the UpdateLock state are done on our handler, outside
3084        // the activity manager's locks.  The new state is determined based on the
3085        // state *now* of the relevant activity record.  The object is passed to
3086        // the handler solely for logging detail, not to be consulted/modified.
3087        final boolean nextState = r != null && r.immersive;
3088        mHandler.sendMessage(
3089                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3090    }
3091
3092    final void applyUpdateVrModeLocked(ActivityRecord r) {
3093        mHandler.sendMessage(
3094                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3095    }
3096
3097    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3098        mHandler.sendMessage(
3099                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3100    }
3101
3102    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3103            ComponentName callingPackage, boolean immediate) {
3104        VrManagerInternal vrService =
3105                LocalServices.getService(VrManagerInternal.class);
3106        if (immediate) {
3107            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3108        } else {
3109            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3110        }
3111    }
3112
3113    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3114        Message msg = Message.obtain();
3115        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3116        msg.obj = r.task.askedCompatMode ? null : r;
3117        mUiHandler.sendMessage(msg);
3118    }
3119
3120    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3121        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3122                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3123            final Message msg = Message.obtain();
3124            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3125            msg.obj = r;
3126            mUiHandler.sendMessage(msg);
3127        }
3128    }
3129
3130    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3131            String what, Object obj, ProcessRecord srcApp) {
3132        app.lastActivityTime = now;
3133
3134        if (app.activities.size() > 0) {
3135            // Don't want to touch dependent processes that are hosting activities.
3136            return index;
3137        }
3138
3139        int lrui = mLruProcesses.lastIndexOf(app);
3140        if (lrui < 0) {
3141            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3142                    + what + " " + obj + " from " + srcApp);
3143            return index;
3144        }
3145
3146        if (lrui >= index) {
3147            // Don't want to cause this to move dependent processes *back* in the
3148            // list as if they were less frequently used.
3149            return index;
3150        }
3151
3152        if (lrui >= mLruProcessActivityStart) {
3153            // Don't want to touch dependent processes that are hosting activities.
3154            return index;
3155        }
3156
3157        mLruProcesses.remove(lrui);
3158        if (index > 0) {
3159            index--;
3160        }
3161        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3162                + " in LRU list: " + app);
3163        mLruProcesses.add(index, app);
3164        return index;
3165    }
3166
3167    static void killProcessGroup(int uid, int pid) {
3168        if (sKillHandler != null) {
3169            sKillHandler.sendMessage(
3170                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3171        } else {
3172            Slog.w(TAG, "Asked to kill process group before system bringup!");
3173            Process.killProcessGroup(uid, pid);
3174        }
3175    }
3176
3177    final void removeLruProcessLocked(ProcessRecord app) {
3178        int lrui = mLruProcesses.lastIndexOf(app);
3179        if (lrui >= 0) {
3180            if (!app.killed) {
3181                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3182                Process.killProcessQuiet(app.pid);
3183                killProcessGroup(app.uid, app.pid);
3184            }
3185            if (lrui <= mLruProcessActivityStart) {
3186                mLruProcessActivityStart--;
3187            }
3188            if (lrui <= mLruProcessServiceStart) {
3189                mLruProcessServiceStart--;
3190            }
3191            mLruProcesses.remove(lrui);
3192        }
3193    }
3194
3195    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3196            ProcessRecord client) {
3197        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3198                || app.treatLikeActivity;
3199        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3200        if (!activityChange && hasActivity) {
3201            // The process has activities, so we are only allowing activity-based adjustments
3202            // to move it.  It should be kept in the front of the list with other
3203            // processes that have activities, and we don't want those to change their
3204            // order except due to activity operations.
3205            return;
3206        }
3207
3208        mLruSeq++;
3209        final long now = SystemClock.uptimeMillis();
3210        app.lastActivityTime = now;
3211
3212        // First a quick reject: if the app is already at the position we will
3213        // put it, then there is nothing to do.
3214        if (hasActivity) {
3215            final int N = mLruProcesses.size();
3216            if (N > 0 && mLruProcesses.get(N-1) == app) {
3217                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3218                return;
3219            }
3220        } else {
3221            if (mLruProcessServiceStart > 0
3222                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3223                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3224                return;
3225            }
3226        }
3227
3228        int lrui = mLruProcesses.lastIndexOf(app);
3229
3230        if (app.persistent && lrui >= 0) {
3231            // We don't care about the position of persistent processes, as long as
3232            // they are in the list.
3233            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3234            return;
3235        }
3236
3237        /* In progress: compute new position first, so we can avoid doing work
3238           if the process is not actually going to move.  Not yet working.
3239        int addIndex;
3240        int nextIndex;
3241        boolean inActivity = false, inService = false;
3242        if (hasActivity) {
3243            // Process has activities, put it at the very tipsy-top.
3244            addIndex = mLruProcesses.size();
3245            nextIndex = mLruProcessServiceStart;
3246            inActivity = true;
3247        } else if (hasService) {
3248            // Process has services, put it at the top of the service list.
3249            addIndex = mLruProcessActivityStart;
3250            nextIndex = mLruProcessServiceStart;
3251            inActivity = true;
3252            inService = true;
3253        } else  {
3254            // Process not otherwise of interest, it goes to the top of the non-service area.
3255            addIndex = mLruProcessServiceStart;
3256            if (client != null) {
3257                int clientIndex = mLruProcesses.lastIndexOf(client);
3258                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3259                        + app);
3260                if (clientIndex >= 0 && addIndex > clientIndex) {
3261                    addIndex = clientIndex;
3262                }
3263            }
3264            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3265        }
3266
3267        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3268                + mLruProcessActivityStart + "): " + app);
3269        */
3270
3271        if (lrui >= 0) {
3272            if (lrui < mLruProcessActivityStart) {
3273                mLruProcessActivityStart--;
3274            }
3275            if (lrui < mLruProcessServiceStart) {
3276                mLruProcessServiceStart--;
3277            }
3278            /*
3279            if (addIndex > lrui) {
3280                addIndex--;
3281            }
3282            if (nextIndex > lrui) {
3283                nextIndex--;
3284            }
3285            */
3286            mLruProcesses.remove(lrui);
3287        }
3288
3289        /*
3290        mLruProcesses.add(addIndex, app);
3291        if (inActivity) {
3292            mLruProcessActivityStart++;
3293        }
3294        if (inService) {
3295            mLruProcessActivityStart++;
3296        }
3297        */
3298
3299        int nextIndex;
3300        if (hasActivity) {
3301            final int N = mLruProcesses.size();
3302            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3303                // Process doesn't have activities, but has clients with
3304                // activities...  move it up, but one below the top (the top
3305                // should always have a real activity).
3306                if (DEBUG_LRU) Slog.d(TAG_LRU,
3307                        "Adding to second-top of LRU activity list: " + app);
3308                mLruProcesses.add(N - 1, app);
3309                // To keep it from spamming the LRU list (by making a bunch of clients),
3310                // we will push down any other entries owned by the app.
3311                final int uid = app.info.uid;
3312                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3313                    ProcessRecord subProc = mLruProcesses.get(i);
3314                    if (subProc.info.uid == uid) {
3315                        // We want to push this one down the list.  If the process after
3316                        // it is for the same uid, however, don't do so, because we don't
3317                        // want them internally to be re-ordered.
3318                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3319                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3320                                    "Pushing uid " + uid + " swapping at " + i + ": "
3321                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3322                            ProcessRecord tmp = mLruProcesses.get(i);
3323                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3324                            mLruProcesses.set(i - 1, tmp);
3325                            i--;
3326                        }
3327                    } else {
3328                        // A gap, we can stop here.
3329                        break;
3330                    }
3331                }
3332            } else {
3333                // Process has activities, put it at the very tipsy-top.
3334                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3335                mLruProcesses.add(app);
3336            }
3337            nextIndex = mLruProcessServiceStart;
3338        } else if (hasService) {
3339            // Process has services, put it at the top of the service list.
3340            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3341            mLruProcesses.add(mLruProcessActivityStart, app);
3342            nextIndex = mLruProcessServiceStart;
3343            mLruProcessActivityStart++;
3344        } else  {
3345            // Process not otherwise of interest, it goes to the top of the non-service area.
3346            int index = mLruProcessServiceStart;
3347            if (client != null) {
3348                // If there is a client, don't allow the process to be moved up higher
3349                // in the list than that client.
3350                int clientIndex = mLruProcesses.lastIndexOf(client);
3351                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3352                        + " when updating " + app);
3353                if (clientIndex <= lrui) {
3354                    // Don't allow the client index restriction to push it down farther in the
3355                    // list than it already is.
3356                    clientIndex = lrui;
3357                }
3358                if (clientIndex >= 0 && index > clientIndex) {
3359                    index = clientIndex;
3360                }
3361            }
3362            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3363            mLruProcesses.add(index, app);
3364            nextIndex = index-1;
3365            mLruProcessActivityStart++;
3366            mLruProcessServiceStart++;
3367        }
3368
3369        // If the app is currently using a content provider or service,
3370        // bump those processes as well.
3371        for (int j=app.connections.size()-1; j>=0; j--) {
3372            ConnectionRecord cr = app.connections.valueAt(j);
3373            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3374                    && cr.binding.service.app != null
3375                    && cr.binding.service.app.lruSeq != mLruSeq
3376                    && !cr.binding.service.app.persistent) {
3377                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3378                        "service connection", cr, app);
3379            }
3380        }
3381        for (int j=app.conProviders.size()-1; j>=0; j--) {
3382            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3383            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3384                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3385                        "provider reference", cpr, app);
3386            }
3387        }
3388    }
3389
3390    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3391        if (uid == Process.SYSTEM_UID) {
3392            // The system gets to run in any process.  If there are multiple
3393            // processes with the same uid, just pick the first (this
3394            // should never happen).
3395            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3396            if (procs == null) return null;
3397            final int procCount = procs.size();
3398            for (int i = 0; i < procCount; i++) {
3399                final int procUid = procs.keyAt(i);
3400                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3401                    // Don't use an app process or different user process for system component.
3402                    continue;
3403                }
3404                return procs.valueAt(i);
3405            }
3406        }
3407        ProcessRecord proc = mProcessNames.get(processName, uid);
3408        if (false && proc != null && !keepIfLarge
3409                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3410                && proc.lastCachedPss >= 4000) {
3411            // Turn this condition on to cause killing to happen regularly, for testing.
3412            if (proc.baseProcessTracker != null) {
3413                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3414            }
3415            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3416        } else if (proc != null && !keepIfLarge
3417                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3418                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3419            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3420            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3421                if (proc.baseProcessTracker != null) {
3422                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3423                }
3424                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3425            }
3426        }
3427        return proc;
3428    }
3429
3430    void notifyPackageUse(String packageName, int reason) {
3431        IPackageManager pm = AppGlobals.getPackageManager();
3432        try {
3433            pm.notifyPackageUse(packageName, reason);
3434        } catch (RemoteException e) {
3435        }
3436    }
3437
3438    boolean isNextTransitionForward() {
3439        int transit = mWindowManager.getPendingAppTransition();
3440        return transit == TRANSIT_ACTIVITY_OPEN
3441                || transit == TRANSIT_TASK_OPEN
3442                || transit == TRANSIT_TASK_TO_FRONT;
3443    }
3444
3445    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3446            String processName, String abiOverride, int uid, Runnable crashHandler) {
3447        synchronized(this) {
3448            ApplicationInfo info = new ApplicationInfo();
3449            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3450            // For isolated processes, the former contains the parent's uid and the latter the
3451            // actual uid of the isolated process.
3452            // In the special case introduced by this method (which is, starting an isolated
3453            // process directly from the SystemServer without an actual parent app process) the
3454            // closest thing to a parent's uid is SYSTEM_UID.
3455            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3456            // the |isolated| logic in the ProcessRecord constructor.
3457            info.uid = Process.SYSTEM_UID;
3458            info.processName = processName;
3459            info.className = entryPoint;
3460            info.packageName = "android";
3461            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3462                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3463                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3464                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3465                    crashHandler);
3466            return proc != null ? proc.pid : 0;
3467        }
3468    }
3469
3470    final ProcessRecord startProcessLocked(String processName,
3471            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3472            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3473            boolean isolated, boolean keepIfLarge) {
3474        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3475                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3476                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3477                null /* crashHandler */);
3478    }
3479
3480    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3481            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3482            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3483            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3484        long startTime = SystemClock.elapsedRealtime();
3485        ProcessRecord app;
3486        if (!isolated) {
3487            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3488            checkTime(startTime, "startProcess: after getProcessRecord");
3489
3490            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3491                // If we are in the background, then check to see if this process
3492                // is bad.  If so, we will just silently fail.
3493                if (mAppErrors.isBadProcessLocked(info)) {
3494                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3495                            + "/" + info.processName);
3496                    return null;
3497                }
3498            } else {
3499                // When the user is explicitly starting a process, then clear its
3500                // crash count so that we won't make it bad until they see at
3501                // least one crash dialog again, and make the process good again
3502                // if it had been bad.
3503                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3504                        + "/" + info.processName);
3505                mAppErrors.resetProcessCrashTimeLocked(info);
3506                if (mAppErrors.isBadProcessLocked(info)) {
3507                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3508                            UserHandle.getUserId(info.uid), info.uid,
3509                            info.processName);
3510                    mAppErrors.clearBadProcessLocked(info);
3511                    if (app != null) {
3512                        app.bad = false;
3513                    }
3514                }
3515            }
3516        } else {
3517            // If this is an isolated process, it can't re-use an existing process.
3518            app = null;
3519        }
3520
3521        // app launch boost for big.little configurations
3522        // use cpusets to migrate freshly launched tasks to big cores
3523        synchronized(ActivityManagerService.this) {
3524            nativeMigrateToBoost();
3525            mIsBoosted = true;
3526            mBoostStartTime = SystemClock.uptimeMillis();
3527            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3528            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3529        }
3530
3531        // We don't have to do anything more if:
3532        // (1) There is an existing application record; and
3533        // (2) The caller doesn't think it is dead, OR there is no thread
3534        //     object attached to it so we know it couldn't have crashed; and
3535        // (3) There is a pid assigned to it, so it is either starting or
3536        //     already running.
3537        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3538                + " app=" + app + " knownToBeDead=" + knownToBeDead
3539                + " thread=" + (app != null ? app.thread : null)
3540                + " pid=" + (app != null ? app.pid : -1));
3541        if (app != null && app.pid > 0) {
3542            if (!knownToBeDead || app.thread == null) {
3543                // We already have the app running, or are waiting for it to
3544                // come up (we have a pid but not yet its thread), so keep it.
3545                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3546                // If this is a new package in the process, add the package to the list
3547                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3548                checkTime(startTime, "startProcess: done, added package to proc");
3549                return app;
3550            }
3551
3552            // An application record is attached to a previous process,
3553            // clean it up now.
3554            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3555            checkTime(startTime, "startProcess: bad proc running, killing");
3556            killProcessGroup(app.uid, app.pid);
3557            handleAppDiedLocked(app, true, true);
3558            checkTime(startTime, "startProcess: done killing old proc");
3559        }
3560
3561        String hostingNameStr = hostingName != null
3562                ? hostingName.flattenToShortString() : null;
3563
3564        if (app == null) {
3565            checkTime(startTime, "startProcess: creating new process record");
3566            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3567            if (app == null) {
3568                Slog.w(TAG, "Failed making new process record for "
3569                        + processName + "/" + info.uid + " isolated=" + isolated);
3570                return null;
3571            }
3572            app.crashHandler = crashHandler;
3573            checkTime(startTime, "startProcess: done creating new process record");
3574        } else {
3575            // If this is a new package in the process, add the package to the list
3576            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3577            checkTime(startTime, "startProcess: added package to existing proc");
3578        }
3579
3580        // If the system is not ready yet, then hold off on starting this
3581        // process until it is.
3582        if (!mProcessesReady
3583                && !isAllowedWhileBooting(info)
3584                && !allowWhileBooting) {
3585            if (!mProcessesOnHold.contains(app)) {
3586                mProcessesOnHold.add(app);
3587            }
3588            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3589                    "System not ready, putting on hold: " + app);
3590            checkTime(startTime, "startProcess: returning with proc on hold");
3591            return app;
3592        }
3593
3594        checkTime(startTime, "startProcess: stepping in to startProcess");
3595        startProcessLocked(
3596                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3597        checkTime(startTime, "startProcess: done starting proc!");
3598        return (app.pid != 0) ? app : null;
3599    }
3600
3601    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3602        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3603    }
3604
3605    private final void startProcessLocked(ProcessRecord app,
3606            String hostingType, String hostingNameStr) {
3607        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3608                null /* entryPoint */, null /* entryPointArgs */);
3609    }
3610
3611    private final void startProcessLocked(ProcessRecord app, String hostingType,
3612            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3613        long startTime = SystemClock.elapsedRealtime();
3614        if (app.pid > 0 && app.pid != MY_PID) {
3615            checkTime(startTime, "startProcess: removing from pids map");
3616            synchronized (mPidsSelfLocked) {
3617                mPidsSelfLocked.remove(app.pid);
3618                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3619            }
3620            checkTime(startTime, "startProcess: done removing from pids map");
3621            app.setPid(0);
3622        }
3623
3624        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3625                "startProcessLocked removing on hold: " + app);
3626        mProcessesOnHold.remove(app);
3627
3628        checkTime(startTime, "startProcess: starting to update cpu stats");
3629        updateCpuStats();
3630        checkTime(startTime, "startProcess: done updating cpu stats");
3631
3632        try {
3633            try {
3634                final int userId = UserHandle.getUserId(app.uid);
3635                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3636            } catch (RemoteException e) {
3637                throw e.rethrowAsRuntimeException();
3638            }
3639
3640            int uid = app.uid;
3641            int[] gids = null;
3642            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3643            if (!app.isolated) {
3644                int[] permGids = null;
3645                try {
3646                    checkTime(startTime, "startProcess: getting gids from package manager");
3647                    final IPackageManager pm = AppGlobals.getPackageManager();
3648                    permGids = pm.getPackageGids(app.info.packageName,
3649                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3650                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3651                            MountServiceInternal.class);
3652                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3653                            app.info.packageName);
3654                } catch (RemoteException e) {
3655                    throw e.rethrowAsRuntimeException();
3656                }
3657
3658                /*
3659                 * Add shared application and profile GIDs so applications can share some
3660                 * resources like shared libraries and access user-wide resources
3661                 */
3662                if (ArrayUtils.isEmpty(permGids)) {
3663                    gids = new int[2];
3664                } else {
3665                    gids = new int[permGids.length + 2];
3666                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3667                }
3668                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3669                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3670            }
3671            checkTime(startTime, "startProcess: building args");
3672            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3673                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3674                        && mTopComponent != null
3675                        && app.processName.equals(mTopComponent.getPackageName())) {
3676                    uid = 0;
3677                }
3678                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3679                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3680                    uid = 0;
3681                }
3682            }
3683            int debugFlags = 0;
3684            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3685                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3686                // Also turn on CheckJNI for debuggable apps. It's quite
3687                // awkward to turn on otherwise.
3688                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3689            }
3690            // Run the app in safe mode if its manifest requests so or the
3691            // system is booted in safe mode.
3692            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3693                mSafeMode == true) {
3694                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3695            }
3696            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3697                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3698            }
3699            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3700            if ("true".equals(genDebugInfoProperty)) {
3701                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3702            }
3703            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3704                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3705            }
3706            if ("1".equals(SystemProperties.get("debug.assert"))) {
3707                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3708            }
3709            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3710                // Enable all debug flags required by the native debugger.
3711                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3712                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3713                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3714                mNativeDebuggingApp = null;
3715            }
3716
3717            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3718            if (requiredAbi == null) {
3719                requiredAbi = Build.SUPPORTED_ABIS[0];
3720            }
3721
3722            String instructionSet = null;
3723            if (app.info.primaryCpuAbi != null) {
3724                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3725            }
3726
3727            app.gids = gids;
3728            app.requiredAbi = requiredAbi;
3729            app.instructionSet = instructionSet;
3730
3731            // Start the process.  It will either succeed and return a result containing
3732            // the PID of the new process, or else throw a RuntimeException.
3733            boolean isActivityProcess = (entryPoint == null);
3734            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3735            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3736                    app.processName);
3737            checkTime(startTime, "startProcess: asking zygote to start proc");
3738            Process.ProcessStartResult startResult = Process.start(entryPoint,
3739                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3740                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3741                    app.info.dataDir, entryPointArgs);
3742            checkTime(startTime, "startProcess: returned from zygote!");
3743            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3744
3745            if (app.isolated) {
3746                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3747            }
3748            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3749            checkTime(startTime, "startProcess: done updating battery stats");
3750
3751            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3752                    UserHandle.getUserId(uid), startResult.pid, uid,
3753                    app.processName, hostingType,
3754                    hostingNameStr != null ? hostingNameStr : "");
3755
3756            try {
3757                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3758                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3759            } catch (RemoteException ex) {
3760                // Ignore
3761            }
3762
3763            if (app.persistent) {
3764                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3765            }
3766
3767            checkTime(startTime, "startProcess: building log message");
3768            StringBuilder buf = mStringBuilder;
3769            buf.setLength(0);
3770            buf.append("Start proc ");
3771            buf.append(startResult.pid);
3772            buf.append(':');
3773            buf.append(app.processName);
3774            buf.append('/');
3775            UserHandle.formatUid(buf, uid);
3776            if (!isActivityProcess) {
3777                buf.append(" [");
3778                buf.append(entryPoint);
3779                buf.append("]");
3780            }
3781            buf.append(" for ");
3782            buf.append(hostingType);
3783            if (hostingNameStr != null) {
3784                buf.append(" ");
3785                buf.append(hostingNameStr);
3786            }
3787            Slog.i(TAG, buf.toString());
3788            app.setPid(startResult.pid);
3789            app.usingWrapper = startResult.usingWrapper;
3790            app.removed = false;
3791            app.killed = false;
3792            app.killedByAm = false;
3793            checkTime(startTime, "startProcess: starting to update pids map");
3794            synchronized (mPidsSelfLocked) {
3795                this.mPidsSelfLocked.put(startResult.pid, app);
3796                if (isActivityProcess) {
3797                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3798                    msg.obj = app;
3799                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3800                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3801                }
3802            }
3803            checkTime(startTime, "startProcess: done updating pids map");
3804        } catch (RuntimeException e) {
3805            Slog.e(TAG, "Failure starting process " + app.processName, e);
3806
3807            // Something went very wrong while trying to start this process; one
3808            // common case is when the package is frozen due to an active
3809            // upgrade. To recover, clean up any active bookkeeping related to
3810            // starting this process. (We already invoked this method once when
3811            // the package was initially frozen through KILL_APPLICATION_MSG, so
3812            // it doesn't hurt to use it again.)
3813            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3814                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3815        }
3816    }
3817
3818    void updateUsageStats(ActivityRecord component, boolean resumed) {
3819        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3820                "updateUsageStats: comp=" + component + "res=" + resumed);
3821        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3822        if (resumed) {
3823            if (mUsageStatsService != null) {
3824                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3825                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3826            }
3827            synchronized (stats) {
3828                stats.noteActivityResumedLocked(component.app.uid);
3829            }
3830        } else {
3831            if (mUsageStatsService != null) {
3832                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3833                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3834            }
3835            synchronized (stats) {
3836                stats.noteActivityPausedLocked(component.app.uid);
3837            }
3838        }
3839    }
3840
3841    Intent getHomeIntent() {
3842        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3843        intent.setComponent(mTopComponent);
3844        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3845        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3846            intent.addCategory(Intent.CATEGORY_HOME);
3847        }
3848        return intent;
3849    }
3850
3851    boolean startHomeActivityLocked(int userId, String reason) {
3852        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3853                && mTopAction == null) {
3854            // We are running in factory test mode, but unable to find
3855            // the factory test app, so just sit around displaying the
3856            // error message and don't try to start anything.
3857            return false;
3858        }
3859        Intent intent = getHomeIntent();
3860        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3861        if (aInfo != null) {
3862            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3863            // Don't do this if the home app is currently being
3864            // instrumented.
3865            aInfo = new ActivityInfo(aInfo);
3866            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3867            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3868                    aInfo.applicationInfo.uid, true);
3869            if (app == null || app.instrumentationClass == null) {
3870                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3871                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3872            }
3873        } else {
3874            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3875        }
3876
3877        return true;
3878    }
3879
3880    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3881        ActivityInfo ai = null;
3882        ComponentName comp = intent.getComponent();
3883        try {
3884            if (comp != null) {
3885                // Factory test.
3886                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3887            } else {
3888                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3889                        intent,
3890                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3891                        flags, userId);
3892
3893                if (info != null) {
3894                    ai = info.activityInfo;
3895                }
3896            }
3897        } catch (RemoteException e) {
3898            // ignore
3899        }
3900
3901        return ai;
3902    }
3903
3904    /**
3905     * Starts the "new version setup screen" if appropriate.
3906     */
3907    void startSetupActivityLocked() {
3908        // Only do this once per boot.
3909        if (mCheckedForSetup) {
3910            return;
3911        }
3912
3913        // We will show this screen if the current one is a different
3914        // version than the last one shown, and we are not running in
3915        // low-level factory test mode.
3916        final ContentResolver resolver = mContext.getContentResolver();
3917        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3918                Settings.Global.getInt(resolver,
3919                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3920            mCheckedForSetup = true;
3921
3922            // See if we should be showing the platform update setup UI.
3923            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3924            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3925                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3926            if (!ris.isEmpty()) {
3927                final ResolveInfo ri = ris.get(0);
3928                String vers = ri.activityInfo.metaData != null
3929                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3930                        : null;
3931                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3932                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3933                            Intent.METADATA_SETUP_VERSION);
3934                }
3935                String lastVers = Settings.Secure.getString(
3936                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3937                if (vers != null && !vers.equals(lastVers)) {
3938                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3939                    intent.setComponent(new ComponentName(
3940                            ri.activityInfo.packageName, ri.activityInfo.name));
3941                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3942                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3943                            null, 0, 0, 0, null, false, false, null, null, null);
3944                }
3945            }
3946        }
3947    }
3948
3949    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3950        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3951    }
3952
3953    void enforceNotIsolatedCaller(String caller) {
3954        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3955            throw new SecurityException("Isolated process not allowed to call " + caller);
3956        }
3957    }
3958
3959    void enforceShellRestriction(String restriction, int userHandle) {
3960        if (Binder.getCallingUid() == Process.SHELL_UID) {
3961            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3962                throw new SecurityException("Shell does not have permission to access user "
3963                        + userHandle);
3964            }
3965        }
3966    }
3967
3968    @Override
3969    public int getFrontActivityScreenCompatMode() {
3970        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3971        synchronized (this) {
3972            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3973        }
3974    }
3975
3976    @Override
3977    public void setFrontActivityScreenCompatMode(int mode) {
3978        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3979                "setFrontActivityScreenCompatMode");
3980        synchronized (this) {
3981            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3982        }
3983    }
3984
3985    @Override
3986    public int getPackageScreenCompatMode(String packageName) {
3987        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3988        synchronized (this) {
3989            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3990        }
3991    }
3992
3993    @Override
3994    public void setPackageScreenCompatMode(String packageName, int mode) {
3995        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3996                "setPackageScreenCompatMode");
3997        synchronized (this) {
3998            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3999        }
4000    }
4001
4002    @Override
4003    public boolean getPackageAskScreenCompat(String packageName) {
4004        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4005        synchronized (this) {
4006            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4007        }
4008    }
4009
4010    @Override
4011    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4012        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4013                "setPackageAskScreenCompat");
4014        synchronized (this) {
4015            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4016        }
4017    }
4018
4019    private boolean hasUsageStatsPermission(String callingPackage) {
4020        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4021                Binder.getCallingUid(), callingPackage);
4022        if (mode == AppOpsManager.MODE_DEFAULT) {
4023            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4024                    == PackageManager.PERMISSION_GRANTED;
4025        }
4026        return mode == AppOpsManager.MODE_ALLOWED;
4027    }
4028
4029    @Override
4030    public int getPackageProcessState(String packageName, String callingPackage) {
4031        if (!hasUsageStatsPermission(callingPackage)) {
4032            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4033                    "getPackageProcessState");
4034        }
4035
4036        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4037        synchronized (this) {
4038            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4039                final ProcessRecord proc = mLruProcesses.get(i);
4040                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4041                        || procState > proc.setProcState) {
4042                    boolean found = false;
4043                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4044                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4045                            procState = proc.setProcState;
4046                            found = true;
4047                        }
4048                    }
4049                    if (proc.pkgDeps != null && !found) {
4050                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4051                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4052                                procState = proc.setProcState;
4053                                break;
4054                            }
4055                        }
4056                    }
4057                }
4058            }
4059        }
4060        return procState;
4061    }
4062
4063    @Override
4064    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4065        synchronized (this) {
4066            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4067            if (app == null) {
4068                return false;
4069            }
4070            if (app.trimMemoryLevel < level && app.thread != null &&
4071                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4072                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4073                try {
4074                    app.thread.scheduleTrimMemory(level);
4075                    app.trimMemoryLevel = level;
4076                    return true;
4077                } catch (RemoteException e) {
4078                    // Fallthrough to failure case.
4079                }
4080            }
4081        }
4082        return false;
4083    }
4084
4085    private void dispatchProcessesChanged() {
4086        int N;
4087        synchronized (this) {
4088            N = mPendingProcessChanges.size();
4089            if (mActiveProcessChanges.length < N) {
4090                mActiveProcessChanges = new ProcessChangeItem[N];
4091            }
4092            mPendingProcessChanges.toArray(mActiveProcessChanges);
4093            mPendingProcessChanges.clear();
4094            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4095                    "*** Delivering " + N + " process changes");
4096        }
4097
4098        int i = mProcessObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102            if (observer != null) {
4103                try {
4104                    for (int j=0; j<N; j++) {
4105                        ProcessChangeItem item = mActiveProcessChanges[j];
4106                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4107                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4108                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4109                                    + item.uid + ": " + item.foregroundActivities);
4110                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4111                                    item.foregroundActivities);
4112                        }
4113                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4114                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4115                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4116                                    + ": " + item.processState);
4117                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4118                        }
4119                    }
4120                } catch (RemoteException e) {
4121                }
4122            }
4123        }
4124        mProcessObservers.finishBroadcast();
4125
4126        synchronized (this) {
4127            for (int j=0; j<N; j++) {
4128                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4129            }
4130        }
4131    }
4132
4133    private void dispatchProcessDied(int pid, int uid) {
4134        int i = mProcessObservers.beginBroadcast();
4135        while (i > 0) {
4136            i--;
4137            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4138            if (observer != null) {
4139                try {
4140                    observer.onProcessDied(pid, uid);
4141                } catch (RemoteException e) {
4142                }
4143            }
4144        }
4145        mProcessObservers.finishBroadcast();
4146    }
4147
4148    private void dispatchUidsChanged() {
4149        int N;
4150        synchronized (this) {
4151            N = mPendingUidChanges.size();
4152            if (mActiveUidChanges.length < N) {
4153                mActiveUidChanges = new UidRecord.ChangeItem[N];
4154            }
4155            for (int i=0; i<N; i++) {
4156                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4157                mActiveUidChanges[i] = change;
4158                if (change.uidRecord != null) {
4159                    change.uidRecord.pendingChange = null;
4160                    change.uidRecord = null;
4161                }
4162            }
4163            mPendingUidChanges.clear();
4164            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4165                    "*** Delivering " + N + " uid changes");
4166        }
4167
4168        if (mLocalPowerManager != null) {
4169            for (int j=0; j<N; j++) {
4170                UidRecord.ChangeItem item = mActiveUidChanges[j];
4171                if (item.change == UidRecord.CHANGE_GONE
4172                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4173                    mLocalPowerManager.uidGone(item.uid);
4174                } else {
4175                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4176                }
4177            }
4178        }
4179
4180        int i = mUidObservers.beginBroadcast();
4181        while (i > 0) {
4182            i--;
4183            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4184            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4185            if (observer != null) {
4186                try {
4187                    for (int j=0; j<N; j++) {
4188                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4189                        final int change = item.change;
4190                        UidRecord validateUid = null;
4191                        if (VALIDATE_UID_STATES && i == 0) {
4192                            validateUid = mValidateUids.get(item.uid);
4193                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4194                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4195                                validateUid = new UidRecord(item.uid);
4196                                mValidateUids.put(item.uid, validateUid);
4197                            }
4198                        }
4199                        if (change == UidRecord.CHANGE_IDLE
4200                                || change == UidRecord.CHANGE_GONE_IDLE) {
4201                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4202                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4203                                        "UID idle uid=" + item.uid);
4204                                observer.onUidIdle(item.uid);
4205                            }
4206                            if (VALIDATE_UID_STATES && i == 0) {
4207                                if (validateUid != null) {
4208                                    validateUid.idle = true;
4209                                }
4210                            }
4211                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4212                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4213                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4214                                        "UID active uid=" + item.uid);
4215                                observer.onUidActive(item.uid);
4216                            }
4217                            if (VALIDATE_UID_STATES && i == 0) {
4218                                validateUid.idle = false;
4219                            }
4220                        }
4221                        if (change == UidRecord.CHANGE_GONE
4222                                || change == UidRecord.CHANGE_GONE_IDLE) {
4223                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4224                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4225                                        "UID gone uid=" + item.uid);
4226                                observer.onUidGone(item.uid);
4227                            }
4228                            if (VALIDATE_UID_STATES && i == 0) {
4229                                if (validateUid != null) {
4230                                    mValidateUids.remove(item.uid);
4231                                }
4232                            }
4233                        } else {
4234                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4235                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4236                                        "UID CHANGED uid=" + item.uid
4237                                                + ": " + item.processState);
4238                                observer.onUidStateChanged(item.uid, item.processState);
4239                            }
4240                            if (VALIDATE_UID_STATES && i == 0) {
4241                                validateUid.curProcState = validateUid.setProcState
4242                                        = item.processState;
4243                            }
4244                        }
4245                    }
4246                } catch (RemoteException e) {
4247                }
4248            }
4249        }
4250        mUidObservers.finishBroadcast();
4251
4252        synchronized (this) {
4253            for (int j=0; j<N; j++) {
4254                mAvailUidChanges.add(mActiveUidChanges[j]);
4255            }
4256        }
4257    }
4258
4259    @Override
4260    public final int startActivity(IApplicationThread caller, String callingPackage,
4261            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4262            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4263        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4264                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4265                UserHandle.getCallingUserId());
4266    }
4267
4268    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4269        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4270        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4271                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4272                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4273
4274        // TODO: Switch to user app stacks here.
4275        String mimeType = intent.getType();
4276        final Uri data = intent.getData();
4277        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4278            mimeType = getProviderMimeType(data, userId);
4279        }
4280        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4281
4282        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4283        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4284                null, 0, 0, null, null, null, null, false, userId, container, null);
4285    }
4286
4287    @Override
4288    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4289            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4290            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4291        enforceNotIsolatedCaller("startActivity");
4292        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4293                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4294        // TODO: Switch to user app stacks here.
4295        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4296                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4297                profilerInfo, null, null, bOptions, false, userId, null, null);
4298    }
4299
4300    @Override
4301    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4302            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4303            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4304            int userId) {
4305
4306        // This is very dangerous -- it allows you to perform a start activity (including
4307        // permission grants) as any app that may launch one of your own activities.  So
4308        // we will only allow this to be done from activities that are part of the core framework,
4309        // and then only when they are running as the system.
4310        final ActivityRecord sourceRecord;
4311        final int targetUid;
4312        final String targetPackage;
4313        synchronized (this) {
4314            if (resultTo == null) {
4315                throw new SecurityException("Must be called from an activity");
4316            }
4317            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4318            if (sourceRecord == null) {
4319                throw new SecurityException("Called with bad activity token: " + resultTo);
4320            }
4321            if (!sourceRecord.info.packageName.equals("android")) {
4322                throw new SecurityException(
4323                        "Must be called from an activity that is declared in the android package");
4324            }
4325            if (sourceRecord.app == null) {
4326                throw new SecurityException("Called without a process attached to activity");
4327            }
4328            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4329                // This is still okay, as long as this activity is running under the
4330                // uid of the original calling activity.
4331                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4332                    throw new SecurityException(
4333                            "Calling activity in uid " + sourceRecord.app.uid
4334                                    + " must be system uid or original calling uid "
4335                                    + sourceRecord.launchedFromUid);
4336                }
4337            }
4338            if (ignoreTargetSecurity) {
4339                if (intent.getComponent() == null) {
4340                    throw new SecurityException(
4341                            "Component must be specified with ignoreTargetSecurity");
4342                }
4343                if (intent.getSelector() != null) {
4344                    throw new SecurityException(
4345                            "Selector not allowed with ignoreTargetSecurity");
4346                }
4347            }
4348            targetUid = sourceRecord.launchedFromUid;
4349            targetPackage = sourceRecord.launchedFromPackage;
4350        }
4351
4352        if (userId == UserHandle.USER_NULL) {
4353            userId = UserHandle.getUserId(sourceRecord.app.uid);
4354        }
4355
4356        // TODO: Switch to user app stacks here.
4357        try {
4358            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4359                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4360                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4361            return ret;
4362        } catch (SecurityException e) {
4363            // XXX need to figure out how to propagate to original app.
4364            // A SecurityException here is generally actually a fault of the original
4365            // calling activity (such as a fairly granting permissions), so propagate it
4366            // back to them.
4367            /*
4368            StringBuilder msg = new StringBuilder();
4369            msg.append("While launching");
4370            msg.append(intent.toString());
4371            msg.append(": ");
4372            msg.append(e.getMessage());
4373            */
4374            throw e;
4375        }
4376    }
4377
4378    @Override
4379    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4380            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4381            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4382        enforceNotIsolatedCaller("startActivityAndWait");
4383        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4384                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4385        WaitResult res = new WaitResult();
4386        // TODO: Switch to user app stacks here.
4387        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4388                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4389                bOptions, false, userId, null, null);
4390        return res;
4391    }
4392
4393    @Override
4394    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4395            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4396            int startFlags, Configuration config, Bundle bOptions, int userId) {
4397        enforceNotIsolatedCaller("startActivityWithConfig");
4398        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4399                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4400        // TODO: Switch to user app stacks here.
4401        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4402                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4403                null, null, config, bOptions, false, userId, null, null);
4404        return ret;
4405    }
4406
4407    @Override
4408    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4409            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4410            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4411            throws TransactionTooLargeException {
4412        enforceNotIsolatedCaller("startActivityIntentSender");
4413        // Refuse possible leaked file descriptors
4414        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4415            throw new IllegalArgumentException("File descriptors passed in Intent");
4416        }
4417
4418        IIntentSender sender = intent.getTarget();
4419        if (!(sender instanceof PendingIntentRecord)) {
4420            throw new IllegalArgumentException("Bad PendingIntent object");
4421        }
4422
4423        PendingIntentRecord pir = (PendingIntentRecord)sender;
4424
4425        synchronized (this) {
4426            // If this is coming from the currently resumed activity, it is
4427            // effectively saying that app switches are allowed at this point.
4428            final ActivityStack stack = getFocusedStack();
4429            if (stack.mResumedActivity != null &&
4430                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4431                mAppSwitchesAllowedTime = 0;
4432            }
4433        }
4434        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4435                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4436        return ret;
4437    }
4438
4439    @Override
4440    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4441            Intent intent, String resolvedType, IVoiceInteractionSession session,
4442            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4443            Bundle bOptions, int userId) {
4444        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4445                != PackageManager.PERMISSION_GRANTED) {
4446            String msg = "Permission Denial: startVoiceActivity() from pid="
4447                    + Binder.getCallingPid()
4448                    + ", uid=" + Binder.getCallingUid()
4449                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4450            Slog.w(TAG, msg);
4451            throw new SecurityException(msg);
4452        }
4453        if (session == null || interactor == null) {
4454            throw new NullPointerException("null session or interactor");
4455        }
4456        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4457                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4458        // TODO: Switch to user app stacks here.
4459        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4460                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4461                null, bOptions, false, userId, null, null);
4462    }
4463
4464    @Override
4465    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4466            throws RemoteException {
4467        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4468        synchronized (this) {
4469            ActivityRecord activity = getFocusedStack().topActivity();
4470            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4471                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4472            }
4473            if (mRunningVoice != null || activity.task.voiceSession != null
4474                    || activity.voiceSession != null) {
4475                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4476                return;
4477            }
4478            if (activity.pendingVoiceInteractionStart) {
4479                Slog.w(TAG, "Pending start of voice interaction already.");
4480                return;
4481            }
4482            activity.pendingVoiceInteractionStart = true;
4483        }
4484        LocalServices.getService(VoiceInteractionManagerInternal.class)
4485                .startLocalVoiceInteraction(callingActivity, options);
4486    }
4487
4488    @Override
4489    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4490        LocalServices.getService(VoiceInteractionManagerInternal.class)
4491                .stopLocalVoiceInteraction(callingActivity);
4492    }
4493
4494    @Override
4495    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4496        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4497                .supportsLocalVoiceInteraction();
4498    }
4499
4500    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4501            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4502        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4503        if (activityToCallback == null) return;
4504        activityToCallback.setVoiceSessionLocked(voiceSession);
4505
4506        // Inform the activity
4507        try {
4508            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4509                    voiceInteractor);
4510            long token = Binder.clearCallingIdentity();
4511            try {
4512                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4513            } finally {
4514                Binder.restoreCallingIdentity(token);
4515            }
4516            // TODO: VI Should we cache the activity so that it's easier to find later
4517            // rather than scan through all the stacks and activities?
4518        } catch (RemoteException re) {
4519            activityToCallback.clearVoiceSessionLocked();
4520            // TODO: VI Should this terminate the voice session?
4521        }
4522    }
4523
4524    @Override
4525    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4526        synchronized (this) {
4527            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4528                if (keepAwake) {
4529                    mVoiceWakeLock.acquire();
4530                } else {
4531                    mVoiceWakeLock.release();
4532                }
4533            }
4534        }
4535    }
4536
4537    @Override
4538    public boolean startNextMatchingActivity(IBinder callingActivity,
4539            Intent intent, Bundle bOptions) {
4540        // Refuse possible leaked file descriptors
4541        if (intent != null && intent.hasFileDescriptors() == true) {
4542            throw new IllegalArgumentException("File descriptors passed in Intent");
4543        }
4544        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4545
4546        synchronized (this) {
4547            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4548            if (r == null) {
4549                ActivityOptions.abort(options);
4550                return false;
4551            }
4552            if (r.app == null || r.app.thread == null) {
4553                // The caller is not running...  d'oh!
4554                ActivityOptions.abort(options);
4555                return false;
4556            }
4557            intent = new Intent(intent);
4558            // The caller is not allowed to change the data.
4559            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4560            // And we are resetting to find the next component...
4561            intent.setComponent(null);
4562
4563            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4564
4565            ActivityInfo aInfo = null;
4566            try {
4567                List<ResolveInfo> resolves =
4568                    AppGlobals.getPackageManager().queryIntentActivities(
4569                            intent, r.resolvedType,
4570                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4571                            UserHandle.getCallingUserId()).getList();
4572
4573                // Look for the original activity in the list...
4574                final int N = resolves != null ? resolves.size() : 0;
4575                for (int i=0; i<N; i++) {
4576                    ResolveInfo rInfo = resolves.get(i);
4577                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4578                            && rInfo.activityInfo.name.equals(r.info.name)) {
4579                        // We found the current one...  the next matching is
4580                        // after it.
4581                        i++;
4582                        if (i<N) {
4583                            aInfo = resolves.get(i).activityInfo;
4584                        }
4585                        if (debug) {
4586                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4587                                    + "/" + r.info.name);
4588                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4589                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4590                        }
4591                        break;
4592                    }
4593                }
4594            } catch (RemoteException e) {
4595            }
4596
4597            if (aInfo == null) {
4598                // Nobody who is next!
4599                ActivityOptions.abort(options);
4600                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4601                return false;
4602            }
4603
4604            intent.setComponent(new ComponentName(
4605                    aInfo.applicationInfo.packageName, aInfo.name));
4606            intent.setFlags(intent.getFlags()&~(
4607                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4608                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4609                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4610                    Intent.FLAG_ACTIVITY_NEW_TASK));
4611
4612            // Okay now we need to start the new activity, replacing the
4613            // currently running activity.  This is a little tricky because
4614            // we want to start the new one as if the current one is finished,
4615            // but not finish the current one first so that there is no flicker.
4616            // And thus...
4617            final boolean wasFinishing = r.finishing;
4618            r.finishing = true;
4619
4620            // Propagate reply information over to the new activity.
4621            final ActivityRecord resultTo = r.resultTo;
4622            final String resultWho = r.resultWho;
4623            final int requestCode = r.requestCode;
4624            r.resultTo = null;
4625            if (resultTo != null) {
4626                resultTo.removeResultsLocked(r, resultWho, requestCode);
4627            }
4628
4629            final long origId = Binder.clearCallingIdentity();
4630            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4631                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4632                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4633                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4634                    false, false, null, null, null);
4635            Binder.restoreCallingIdentity(origId);
4636
4637            r.finishing = wasFinishing;
4638            if (res != ActivityManager.START_SUCCESS) {
4639                return false;
4640            }
4641            return true;
4642        }
4643    }
4644
4645    @Override
4646    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4647        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4648            String msg = "Permission Denial: startActivityFromRecents called without " +
4649                    START_TASKS_FROM_RECENTS;
4650            Slog.w(TAG, msg);
4651            throw new SecurityException(msg);
4652        }
4653        final long origId = Binder.clearCallingIdentity();
4654        try {
4655            synchronized (this) {
4656                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4657            }
4658        } finally {
4659            Binder.restoreCallingIdentity(origId);
4660        }
4661    }
4662
4663    final int startActivityInPackage(int uid, String callingPackage,
4664            Intent intent, String resolvedType, IBinder resultTo,
4665            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4666            IActivityContainer container, TaskRecord inTask) {
4667
4668        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4669                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4670
4671        // TODO: Switch to user app stacks here.
4672        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4673                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4674                null, null, null, bOptions, false, userId, container, inTask);
4675        return ret;
4676    }
4677
4678    @Override
4679    public final int startActivities(IApplicationThread caller, String callingPackage,
4680            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4681            int userId) {
4682        enforceNotIsolatedCaller("startActivities");
4683        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4684                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4685        // TODO: Switch to user app stacks here.
4686        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4687                resolvedTypes, resultTo, bOptions, userId);
4688        return ret;
4689    }
4690
4691    final int startActivitiesInPackage(int uid, String callingPackage,
4692            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4693            Bundle bOptions, int userId) {
4694
4695        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4696                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4697        // TODO: Switch to user app stacks here.
4698        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4699                resultTo, bOptions, userId);
4700        return ret;
4701    }
4702
4703    @Override
4704    public void reportActivityFullyDrawn(IBinder token) {
4705        synchronized (this) {
4706            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4707            if (r == null) {
4708                return;
4709            }
4710            r.reportFullyDrawnLocked();
4711        }
4712    }
4713
4714    @Override
4715    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4716        synchronized (this) {
4717            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4718            if (r == null) {
4719                return;
4720            }
4721            TaskRecord task = r.task;
4722            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4723                // Fixed screen orientation isn't supported when activities aren't in full screen
4724                // mode.
4725                return;
4726            }
4727            final long origId = Binder.clearCallingIdentity();
4728            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4729            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4730                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4731            if (config != null) {
4732                r.frozenBeforeDestroy = true;
4733                if (!updateConfigurationLocked(config, r, false)) {
4734                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4735                }
4736            }
4737            Binder.restoreCallingIdentity(origId);
4738        }
4739    }
4740
4741    @Override
4742    public int getRequestedOrientation(IBinder token) {
4743        synchronized (this) {
4744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4745            if (r == null) {
4746                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4747            }
4748            return mWindowManager.getAppOrientation(r.appToken);
4749        }
4750    }
4751
4752    /**
4753     * This is the internal entry point for handling Activity.finish().
4754     *
4755     * @param token The Binder token referencing the Activity we want to finish.
4756     * @param resultCode Result code, if any, from this Activity.
4757     * @param resultData Result data (Intent), if any, from this Activity.
4758     * @param finishTask Whether to finish the task associated with this Activity.
4759     *
4760     * @return Returns true if the activity successfully finished, or false if it is still running.
4761     */
4762    @Override
4763    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4764            int finishTask) {
4765        // Refuse possible leaked file descriptors
4766        if (resultData != null && resultData.hasFileDescriptors() == true) {
4767            throw new IllegalArgumentException("File descriptors passed in Intent");
4768        }
4769
4770        synchronized(this) {
4771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4772            if (r == null) {
4773                return true;
4774            }
4775            // Keep track of the root activity of the task before we finish it
4776            TaskRecord tr = r.task;
4777            ActivityRecord rootR = tr.getRootActivity();
4778            if (rootR == null) {
4779                Slog.w(TAG, "Finishing task with all activities already finished");
4780            }
4781            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4782            // finish.
4783            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4784                    mStackSupervisor.isLastLockedTask(tr)) {
4785                Slog.i(TAG, "Not finishing task in lock task mode");
4786                mStackSupervisor.showLockTaskToast();
4787                return false;
4788            }
4789            if (mController != null) {
4790                // Find the first activity that is not finishing.
4791                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4792                if (next != null) {
4793                    // ask watcher if this is allowed
4794                    boolean resumeOK = true;
4795                    try {
4796                        resumeOK = mController.activityResuming(next.packageName);
4797                    } catch (RemoteException e) {
4798                        mController = null;
4799                        Watchdog.getInstance().setActivityController(null);
4800                    }
4801
4802                    if (!resumeOK) {
4803                        Slog.i(TAG, "Not finishing activity because controller resumed");
4804                        return false;
4805                    }
4806                }
4807            }
4808            final long origId = Binder.clearCallingIdentity();
4809            try {
4810                boolean res;
4811                final boolean finishWithRootActivity =
4812                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4813                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4814                        || (finishWithRootActivity && r == rootR)) {
4815                    // If requested, remove the task that is associated to this activity only if it
4816                    // was the root activity in the task. The result code and data is ignored
4817                    // because we don't support returning them across task boundaries. Also, to
4818                    // keep backwards compatibility we remove the task from recents when finishing
4819                    // task with root activity.
4820                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4821                    if (!res) {
4822                        Slog.i(TAG, "Removing task failed to finish activity");
4823                    }
4824                } else {
4825                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4826                            resultData, "app-request", true);
4827                    if (!res) {
4828                        Slog.i(TAG, "Failed to finish by app-request");
4829                    }
4830                }
4831                return res;
4832            } finally {
4833                Binder.restoreCallingIdentity(origId);
4834            }
4835        }
4836    }
4837
4838    @Override
4839    public final void finishHeavyWeightApp() {
4840        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4841                != PackageManager.PERMISSION_GRANTED) {
4842            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4843                    + Binder.getCallingPid()
4844                    + ", uid=" + Binder.getCallingUid()
4845                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4846            Slog.w(TAG, msg);
4847            throw new SecurityException(msg);
4848        }
4849
4850        synchronized(this) {
4851            if (mHeavyWeightProcess == null) {
4852                return;
4853            }
4854
4855            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4856            for (int i = 0; i < activities.size(); i++) {
4857                ActivityRecord r = activities.get(i);
4858                if (!r.finishing && r.isInStackLocked()) {
4859                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4860                            null, "finish-heavy", true);
4861                }
4862            }
4863
4864            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4865                    mHeavyWeightProcess.userId, 0));
4866            mHeavyWeightProcess = null;
4867        }
4868    }
4869
4870    @Override
4871    public void crashApplication(int uid, int initialPid, String packageName,
4872            String message) {
4873        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4874                != PackageManager.PERMISSION_GRANTED) {
4875            String msg = "Permission Denial: crashApplication() from pid="
4876                    + Binder.getCallingPid()
4877                    + ", uid=" + Binder.getCallingUid()
4878                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4879            Slog.w(TAG, msg);
4880            throw new SecurityException(msg);
4881        }
4882
4883        synchronized(this) {
4884            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4885        }
4886    }
4887
4888    @Override
4889    public final void finishSubActivity(IBinder token, String resultWho,
4890            int requestCode) {
4891        synchronized(this) {
4892            final long origId = Binder.clearCallingIdentity();
4893            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4894            if (r != null) {
4895                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4896            }
4897            Binder.restoreCallingIdentity(origId);
4898        }
4899    }
4900
4901    @Override
4902    public boolean finishActivityAffinity(IBinder token) {
4903        synchronized(this) {
4904            final long origId = Binder.clearCallingIdentity();
4905            try {
4906                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4907                if (r == null) {
4908                    return false;
4909                }
4910
4911                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4912                // can finish.
4913                final TaskRecord task = r.task;
4914                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4915                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4916                    mStackSupervisor.showLockTaskToast();
4917                    return false;
4918                }
4919                return task.stack.finishActivityAffinityLocked(r);
4920            } finally {
4921                Binder.restoreCallingIdentity(origId);
4922            }
4923        }
4924    }
4925
4926    @Override
4927    public void finishVoiceTask(IVoiceInteractionSession session) {
4928        synchronized (this) {
4929            final long origId = Binder.clearCallingIdentity();
4930            try {
4931                // TODO: VI Consider treating local voice interactions and voice tasks
4932                // differently here
4933                mStackSupervisor.finishVoiceTask(session);
4934            } finally {
4935                Binder.restoreCallingIdentity(origId);
4936            }
4937        }
4938
4939    }
4940
4941    @Override
4942    public boolean releaseActivityInstance(IBinder token) {
4943        synchronized(this) {
4944            final long origId = Binder.clearCallingIdentity();
4945            try {
4946                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4947                if (r == null) {
4948                    return false;
4949                }
4950                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4951            } finally {
4952                Binder.restoreCallingIdentity(origId);
4953            }
4954        }
4955    }
4956
4957    @Override
4958    public void releaseSomeActivities(IApplicationThread appInt) {
4959        synchronized(this) {
4960            final long origId = Binder.clearCallingIdentity();
4961            try {
4962                ProcessRecord app = getRecordForAppLocked(appInt);
4963                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4964            } finally {
4965                Binder.restoreCallingIdentity(origId);
4966            }
4967        }
4968    }
4969
4970    @Override
4971    public boolean willActivityBeVisible(IBinder token) {
4972        synchronized(this) {
4973            ActivityStack stack = ActivityRecord.getStackLocked(token);
4974            if (stack != null) {
4975                return stack.willActivityBeVisibleLocked(token);
4976            }
4977            return false;
4978        }
4979    }
4980
4981    @Override
4982    public void overridePendingTransition(IBinder token, String packageName,
4983            int enterAnim, int exitAnim) {
4984        synchronized(this) {
4985            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4986            if (self == null) {
4987                return;
4988            }
4989
4990            final long origId = Binder.clearCallingIdentity();
4991
4992            if (self.state == ActivityState.RESUMED
4993                    || self.state == ActivityState.PAUSING) {
4994                mWindowManager.overridePendingAppTransition(packageName,
4995                        enterAnim, exitAnim, null);
4996            }
4997
4998            Binder.restoreCallingIdentity(origId);
4999        }
5000    }
5001
5002    /**
5003     * Main function for removing an existing process from the activity manager
5004     * as a result of that process going away.  Clears out all connections
5005     * to the process.
5006     */
5007    private final void handleAppDiedLocked(ProcessRecord app,
5008            boolean restarting, boolean allowRestart) {
5009        int pid = app.pid;
5010        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5011        if (!kept && !restarting) {
5012            removeLruProcessLocked(app);
5013            if (pid > 0) {
5014                ProcessList.remove(pid);
5015            }
5016        }
5017
5018        if (mProfileProc == app) {
5019            clearProfilerLocked();
5020        }
5021
5022        // Remove this application's activities from active lists.
5023        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5024
5025        app.activities.clear();
5026
5027        if (app.instrumentationClass != null) {
5028            Slog.w(TAG, "Crash of app " + app.processName
5029                  + " running instrumentation " + app.instrumentationClass);
5030            Bundle info = new Bundle();
5031            info.putString("shortMsg", "Process crashed.");
5032            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5033        }
5034
5035        if (!restarting && hasVisibleActivities
5036                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5037            // If there was nothing to resume, and we are not already restarting this process, but
5038            // there is a visible activity that is hosted by the process...  then make sure all
5039            // visible activities are running, taking care of restarting this process.
5040            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5041        }
5042    }
5043
5044    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5045        IBinder threadBinder = thread.asBinder();
5046        // Find the application record.
5047        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5048            ProcessRecord rec = mLruProcesses.get(i);
5049            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5050                return i;
5051            }
5052        }
5053        return -1;
5054    }
5055
5056    final ProcessRecord getRecordForAppLocked(
5057            IApplicationThread thread) {
5058        if (thread == null) {
5059            return null;
5060        }
5061
5062        int appIndex = getLRURecordIndexForAppLocked(thread);
5063        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5064    }
5065
5066    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5067        // If there are no longer any background processes running,
5068        // and the app that died was not running instrumentation,
5069        // then tell everyone we are now low on memory.
5070        boolean haveBg = false;
5071        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5072            ProcessRecord rec = mLruProcesses.get(i);
5073            if (rec.thread != null
5074                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5075                haveBg = true;
5076                break;
5077            }
5078        }
5079
5080        if (!haveBg) {
5081            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5082            if (doReport) {
5083                long now = SystemClock.uptimeMillis();
5084                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5085                    doReport = false;
5086                } else {
5087                    mLastMemUsageReportTime = now;
5088                }
5089            }
5090            final ArrayList<ProcessMemInfo> memInfos
5091                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5092            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5093            long now = SystemClock.uptimeMillis();
5094            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5095                ProcessRecord rec = mLruProcesses.get(i);
5096                if (rec == dyingProc || rec.thread == null) {
5097                    continue;
5098                }
5099                if (doReport) {
5100                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5101                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5102                }
5103                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5104                    // The low memory report is overriding any current
5105                    // state for a GC request.  Make sure to do
5106                    // heavy/important/visible/foreground processes first.
5107                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5108                        rec.lastRequestedGc = 0;
5109                    } else {
5110                        rec.lastRequestedGc = rec.lastLowMemory;
5111                    }
5112                    rec.reportLowMemory = true;
5113                    rec.lastLowMemory = now;
5114                    mProcessesToGc.remove(rec);
5115                    addProcessToGcListLocked(rec);
5116                }
5117            }
5118            if (doReport) {
5119                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5120                mHandler.sendMessage(msg);
5121            }
5122            scheduleAppGcsLocked();
5123        }
5124    }
5125
5126    final void appDiedLocked(ProcessRecord app) {
5127       appDiedLocked(app, app.pid, app.thread, false);
5128    }
5129
5130    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5131            boolean fromBinderDied) {
5132        // First check if this ProcessRecord is actually active for the pid.
5133        synchronized (mPidsSelfLocked) {
5134            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5135            if (curProc != app) {
5136                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5137                return;
5138            }
5139        }
5140
5141        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5142        synchronized (stats) {
5143            stats.noteProcessDiedLocked(app.info.uid, pid);
5144        }
5145
5146        if (!app.killed) {
5147            if (!fromBinderDied) {
5148                Process.killProcessQuiet(pid);
5149            }
5150            killProcessGroup(app.uid, pid);
5151            app.killed = true;
5152        }
5153
5154        // Clean up already done if the process has been re-started.
5155        if (app.pid == pid && app.thread != null &&
5156                app.thread.asBinder() == thread.asBinder()) {
5157            boolean doLowMem = app.instrumentationClass == null;
5158            boolean doOomAdj = doLowMem;
5159            if (!app.killedByAm) {
5160                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5161                        + ") has died");
5162                mAllowLowerMemLevel = true;
5163            } else {
5164                // Note that we always want to do oom adj to update our state with the
5165                // new number of procs.
5166                mAllowLowerMemLevel = false;
5167                doLowMem = false;
5168            }
5169            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5170            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5171                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5172            handleAppDiedLocked(app, false, true);
5173
5174            if (doOomAdj) {
5175                updateOomAdjLocked();
5176            }
5177            if (doLowMem) {
5178                doLowMemReportIfNeededLocked(app);
5179            }
5180        } else if (app.pid != pid) {
5181            // A new process has already been started.
5182            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5183                    + ") has died and restarted (pid " + app.pid + ").");
5184            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5185        } else if (DEBUG_PROCESSES) {
5186            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5187                    + thread.asBinder());
5188        }
5189    }
5190
5191    /**
5192     * If a stack trace dump file is configured, dump process stack traces.
5193     * @param clearTraces causes the dump file to be erased prior to the new
5194     *    traces being written, if true; when false, the new traces will be
5195     *    appended to any existing file content.
5196     * @param firstPids of dalvik VM processes to dump stack traces for first
5197     * @param lastPids of dalvik VM processes to dump stack traces for last
5198     * @param nativeProcs optional list of native process names to dump stack crawls
5199     * @return file containing stack traces, or null if no dump file is configured
5200     */
5201    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5202            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5203        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5204        if (tracesPath == null || tracesPath.length() == 0) {
5205            return null;
5206        }
5207
5208        File tracesFile = new File(tracesPath);
5209        try {
5210            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5211            tracesFile.createNewFile();
5212            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5213        } catch (IOException e) {
5214            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5215            return null;
5216        }
5217
5218        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5219        return tracesFile;
5220    }
5221
5222    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5223            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5224        // Use a FileObserver to detect when traces finish writing.
5225        // The order of traces is considered important to maintain for legibility.
5226        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5227            @Override
5228            public synchronized void onEvent(int event, String path) { notify(); }
5229        };
5230
5231        try {
5232            observer.startWatching();
5233
5234            // First collect all of the stacks of the most important pids.
5235            if (firstPids != null) {
5236                try {
5237                    int num = firstPids.size();
5238                    for (int i = 0; i < num; i++) {
5239                        synchronized (observer) {
5240                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5241                                    + firstPids.get(i));
5242                            final long sime = SystemClock.elapsedRealtime();
5243                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5244                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5245                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5246                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5247                        }
5248                    }
5249                } catch (InterruptedException e) {
5250                    Slog.wtf(TAG, e);
5251                }
5252            }
5253
5254            // Next collect the stacks of the native pids
5255            if (nativeProcs != null) {
5256                int[] pids = Process.getPidsForCommands(nativeProcs);
5257                if (pids != null) {
5258                    for (int pid : pids) {
5259                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5260                        final long sime = SystemClock.elapsedRealtime();
5261                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5262                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5263                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5264                    }
5265                }
5266            }
5267
5268            // Lastly, measure CPU usage.
5269            if (processCpuTracker != null) {
5270                processCpuTracker.init();
5271                System.gc();
5272                processCpuTracker.update();
5273                try {
5274                    synchronized (processCpuTracker) {
5275                        processCpuTracker.wait(500); // measure over 1/2 second.
5276                    }
5277                } catch (InterruptedException e) {
5278                }
5279                processCpuTracker.update();
5280
5281                // We'll take the stack crawls of just the top apps using CPU.
5282                final int N = processCpuTracker.countWorkingStats();
5283                int numProcs = 0;
5284                for (int i=0; i<N && numProcs<5; i++) {
5285                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5286                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5287                        numProcs++;
5288                        try {
5289                            synchronized (observer) {
5290                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5291                                        + stats.pid);
5292                                final long stime = SystemClock.elapsedRealtime();
5293                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5294                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5295                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5296                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5297                            }
5298                        } catch (InterruptedException e) {
5299                            Slog.wtf(TAG, e);
5300                        }
5301                    } else if (DEBUG_ANR) {
5302                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5303                                + stats.pid);
5304                    }
5305                }
5306            }
5307        } finally {
5308            observer.stopWatching();
5309        }
5310    }
5311
5312    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5313        if (true || IS_USER_BUILD) {
5314            return;
5315        }
5316        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5317        if (tracesPath == null || tracesPath.length() == 0) {
5318            return;
5319        }
5320
5321        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5322        StrictMode.allowThreadDiskWrites();
5323        try {
5324            final File tracesFile = new File(tracesPath);
5325            final File tracesDir = tracesFile.getParentFile();
5326            final File tracesTmp = new File(tracesDir, "__tmp__");
5327            try {
5328                if (tracesFile.exists()) {
5329                    tracesTmp.delete();
5330                    tracesFile.renameTo(tracesTmp);
5331                }
5332                StringBuilder sb = new StringBuilder();
5333                Time tobj = new Time();
5334                tobj.set(System.currentTimeMillis());
5335                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5336                sb.append(": ");
5337                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5338                sb.append(" since ");
5339                sb.append(msg);
5340                FileOutputStream fos = new FileOutputStream(tracesFile);
5341                fos.write(sb.toString().getBytes());
5342                if (app == null) {
5343                    fos.write("\n*** No application process!".getBytes());
5344                }
5345                fos.close();
5346                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5347            } catch (IOException e) {
5348                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5349                return;
5350            }
5351
5352            if (app != null) {
5353                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5354                firstPids.add(app.pid);
5355                dumpStackTraces(tracesPath, firstPids, null, null, null);
5356            }
5357
5358            File lastTracesFile = null;
5359            File curTracesFile = null;
5360            for (int i=9; i>=0; i--) {
5361                String name = String.format(Locale.US, "slow%02d.txt", i);
5362                curTracesFile = new File(tracesDir, name);
5363                if (curTracesFile.exists()) {
5364                    if (lastTracesFile != null) {
5365                        curTracesFile.renameTo(lastTracesFile);
5366                    } else {
5367                        curTracesFile.delete();
5368                    }
5369                }
5370                lastTracesFile = curTracesFile;
5371            }
5372            tracesFile.renameTo(curTracesFile);
5373            if (tracesTmp.exists()) {
5374                tracesTmp.renameTo(tracesFile);
5375            }
5376        } finally {
5377            StrictMode.setThreadPolicy(oldPolicy);
5378        }
5379    }
5380
5381    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5382        if (!mLaunchWarningShown) {
5383            mLaunchWarningShown = true;
5384            mUiHandler.post(new Runnable() {
5385                @Override
5386                public void run() {
5387                    synchronized (ActivityManagerService.this) {
5388                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5389                        d.show();
5390                        mUiHandler.postDelayed(new Runnable() {
5391                            @Override
5392                            public void run() {
5393                                synchronized (ActivityManagerService.this) {
5394                                    d.dismiss();
5395                                    mLaunchWarningShown = false;
5396                                }
5397                            }
5398                        }, 4000);
5399                    }
5400                }
5401            });
5402        }
5403    }
5404
5405    @Override
5406    public boolean clearApplicationUserData(final String packageName,
5407            final IPackageDataObserver observer, int userId) {
5408        enforceNotIsolatedCaller("clearApplicationUserData");
5409        int uid = Binder.getCallingUid();
5410        int pid = Binder.getCallingPid();
5411        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5412                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5413
5414
5415        long callingId = Binder.clearCallingIdentity();
5416        try {
5417            IPackageManager pm = AppGlobals.getPackageManager();
5418            int pkgUid = -1;
5419            synchronized(this) {
5420                if (getPackageManagerInternalLocked().canPackageBeWiped(
5421                        userId, packageName)) {
5422                    throw new SecurityException(
5423                            "Cannot clear data for a device owner or a profile owner");
5424                }
5425
5426                try {
5427                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5428                } catch (RemoteException e) {
5429                }
5430                if (pkgUid == -1) {
5431                    Slog.w(TAG, "Invalid packageName: " + packageName);
5432                    if (observer != null) {
5433                        try {
5434                            observer.onRemoveCompleted(packageName, false);
5435                        } catch (RemoteException e) {
5436                            Slog.i(TAG, "Observer no longer exists.");
5437                        }
5438                    }
5439                    return false;
5440                }
5441                if (uid == pkgUid || checkComponentPermission(
5442                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5443                        pid, uid, -1, true)
5444                        == PackageManager.PERMISSION_GRANTED) {
5445                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5446                } else {
5447                    throw new SecurityException("PID " + pid + " does not have permission "
5448                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5449                                    + " of package " + packageName);
5450                }
5451
5452                // Remove all tasks match the cleared application package and user
5453                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5454                    final TaskRecord tr = mRecentTasks.get(i);
5455                    final String taskPackageName =
5456                            tr.getBaseIntent().getComponent().getPackageName();
5457                    if (tr.userId != userId) continue;
5458                    if (!taskPackageName.equals(packageName)) continue;
5459                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5460                }
5461            }
5462
5463            final int pkgUidF = pkgUid;
5464            final int userIdF = userId;
5465            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5466                @Override
5467                public void onRemoveCompleted(String packageName, boolean succeeded)
5468                        throws RemoteException {
5469                    synchronized (ActivityManagerService.this) {
5470                        finishForceStopPackageLocked(packageName, pkgUidF);
5471                    }
5472
5473                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5474                            Uri.fromParts("package", packageName, null));
5475                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5476                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5477                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5478                            null, null, 0, null, null, null, null, false, false, userIdF);
5479
5480                    if (observer != null) {
5481                        observer.onRemoveCompleted(packageName, succeeded);
5482                    }
5483                }
5484            };
5485
5486            try {
5487                // Clear application user data
5488                pm.clearApplicationUserData(packageName, localObserver, userId);
5489
5490                synchronized(this) {
5491                    // Remove all permissions granted from/to this package
5492                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5493                }
5494
5495                // Remove all zen rules created by this package; revoke it's zen access.
5496                INotificationManager inm = NotificationManager.getService();
5497                inm.removeAutomaticZenRules(packageName);
5498                inm.setNotificationPolicyAccessGranted(packageName, false);
5499
5500            } catch (RemoteException e) {
5501            }
5502        } finally {
5503            Binder.restoreCallingIdentity(callingId);
5504        }
5505        return true;
5506    }
5507
5508    @Override
5509    public void killBackgroundProcesses(final String packageName, int userId) {
5510        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5511                != PackageManager.PERMISSION_GRANTED &&
5512                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5513                        != PackageManager.PERMISSION_GRANTED) {
5514            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5515                    + Binder.getCallingPid()
5516                    + ", uid=" + Binder.getCallingUid()
5517                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5518            Slog.w(TAG, msg);
5519            throw new SecurityException(msg);
5520        }
5521
5522        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5523                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5524        long callingId = Binder.clearCallingIdentity();
5525        try {
5526            IPackageManager pm = AppGlobals.getPackageManager();
5527            synchronized(this) {
5528                int appId = -1;
5529                try {
5530                    appId = UserHandle.getAppId(
5531                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5532                } catch (RemoteException e) {
5533                }
5534                if (appId == -1) {
5535                    Slog.w(TAG, "Invalid packageName: " + packageName);
5536                    return;
5537                }
5538                killPackageProcessesLocked(packageName, appId, userId,
5539                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5540            }
5541        } finally {
5542            Binder.restoreCallingIdentity(callingId);
5543        }
5544    }
5545
5546    @Override
5547    public void killAllBackgroundProcesses() {
5548        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5549                != PackageManager.PERMISSION_GRANTED) {
5550            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5551                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5552                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5553            Slog.w(TAG, msg);
5554            throw new SecurityException(msg);
5555        }
5556
5557        final long callingId = Binder.clearCallingIdentity();
5558        try {
5559            synchronized (this) {
5560                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5561                final int NP = mProcessNames.getMap().size();
5562                for (int ip = 0; ip < NP; ip++) {
5563                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5564                    final int NA = apps.size();
5565                    for (int ia = 0; ia < NA; ia++) {
5566                        final ProcessRecord app = apps.valueAt(ia);
5567                        if (app.persistent) {
5568                            // We don't kill persistent processes.
5569                            continue;
5570                        }
5571                        if (app.removed) {
5572                            procs.add(app);
5573                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5574                            app.removed = true;
5575                            procs.add(app);
5576                        }
5577                    }
5578                }
5579
5580                final int N = procs.size();
5581                for (int i = 0; i < N; i++) {
5582                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5583                }
5584
5585                mAllowLowerMemLevel = true;
5586
5587                updateOomAdjLocked();
5588                doLowMemReportIfNeededLocked(null);
5589            }
5590        } finally {
5591            Binder.restoreCallingIdentity(callingId);
5592        }
5593    }
5594
5595    /**
5596     * Kills all background processes, except those matching any of the
5597     * specified properties.
5598     *
5599     * @param minTargetSdk the target SDK version at or above which to preserve
5600     *                     processes, or {@code -1} to ignore the target SDK
5601     * @param maxProcState the process state at or below which to preserve
5602     *                     processes, or {@code -1} to ignore the process state
5603     */
5604    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5605        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5606                != PackageManager.PERMISSION_GRANTED) {
5607            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5608                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5609                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5610            Slog.w(TAG, msg);
5611            throw new SecurityException(msg);
5612        }
5613
5614        final long callingId = Binder.clearCallingIdentity();
5615        try {
5616            synchronized (this) {
5617                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5618                final int NP = mProcessNames.getMap().size();
5619                for (int ip = 0; ip < NP; ip++) {
5620                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5621                    final int NA = apps.size();
5622                    for (int ia = 0; ia < NA; ia++) {
5623                        final ProcessRecord app = apps.valueAt(ia);
5624                        if (app.removed) {
5625                            procs.add(app);
5626                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5627                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5628                            app.removed = true;
5629                            procs.add(app);
5630                        }
5631                    }
5632                }
5633
5634                final int N = procs.size();
5635                for (int i = 0; i < N; i++) {
5636                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5637                }
5638            }
5639        } finally {
5640            Binder.restoreCallingIdentity(callingId);
5641        }
5642    }
5643
5644    @Override
5645    public void forceStopPackage(final String packageName, int userId) {
5646        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5647                != PackageManager.PERMISSION_GRANTED) {
5648            String msg = "Permission Denial: forceStopPackage() from pid="
5649                    + Binder.getCallingPid()
5650                    + ", uid=" + Binder.getCallingUid()
5651                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5652            Slog.w(TAG, msg);
5653            throw new SecurityException(msg);
5654        }
5655        final int callingPid = Binder.getCallingPid();
5656        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5657                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5658        long callingId = Binder.clearCallingIdentity();
5659        try {
5660            IPackageManager pm = AppGlobals.getPackageManager();
5661            synchronized(this) {
5662                int[] users = userId == UserHandle.USER_ALL
5663                        ? mUserController.getUsers() : new int[] { userId };
5664                for (int user : users) {
5665                    int pkgUid = -1;
5666                    try {
5667                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5668                                user);
5669                    } catch (RemoteException e) {
5670                    }
5671                    if (pkgUid == -1) {
5672                        Slog.w(TAG, "Invalid packageName: " + packageName);
5673                        continue;
5674                    }
5675                    try {
5676                        pm.setPackageStoppedState(packageName, true, user);
5677                    } catch (RemoteException e) {
5678                    } catch (IllegalArgumentException e) {
5679                        Slog.w(TAG, "Failed trying to unstop package "
5680                                + packageName + ": " + e);
5681                    }
5682                    if (mUserController.isUserRunningLocked(user, 0)) {
5683                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5684                        finishForceStopPackageLocked(packageName, pkgUid);
5685                    }
5686                }
5687            }
5688        } finally {
5689            Binder.restoreCallingIdentity(callingId);
5690        }
5691    }
5692
5693    @Override
5694    public void addPackageDependency(String packageName) {
5695        synchronized (this) {
5696            int callingPid = Binder.getCallingPid();
5697            if (callingPid == Process.myPid()) {
5698                //  Yeah, um, no.
5699                return;
5700            }
5701            ProcessRecord proc;
5702            synchronized (mPidsSelfLocked) {
5703                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5704            }
5705            if (proc != null) {
5706                if (proc.pkgDeps == null) {
5707                    proc.pkgDeps = new ArraySet<String>(1);
5708                }
5709                proc.pkgDeps.add(packageName);
5710            }
5711        }
5712    }
5713
5714    /*
5715     * The pkg name and app id have to be specified.
5716     */
5717    @Override
5718    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5719        if (pkg == null) {
5720            return;
5721        }
5722        // Make sure the uid is valid.
5723        if (appid < 0) {
5724            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5725            return;
5726        }
5727        int callerUid = Binder.getCallingUid();
5728        // Only the system server can kill an application
5729        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5730            // Post an aysnc message to kill the application
5731            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5732            msg.arg1 = appid;
5733            msg.arg2 = 0;
5734            Bundle bundle = new Bundle();
5735            bundle.putString("pkg", pkg);
5736            bundle.putString("reason", reason);
5737            msg.obj = bundle;
5738            mHandler.sendMessage(msg);
5739        } else {
5740            throw new SecurityException(callerUid + " cannot kill pkg: " +
5741                    pkg);
5742        }
5743    }
5744
5745    @Override
5746    public void closeSystemDialogs(String reason) {
5747        enforceNotIsolatedCaller("closeSystemDialogs");
5748
5749        final int pid = Binder.getCallingPid();
5750        final int uid = Binder.getCallingUid();
5751        final long origId = Binder.clearCallingIdentity();
5752        try {
5753            synchronized (this) {
5754                // Only allow this from foreground processes, so that background
5755                // applications can't abuse it to prevent system UI from being shown.
5756                if (uid >= Process.FIRST_APPLICATION_UID) {
5757                    ProcessRecord proc;
5758                    synchronized (mPidsSelfLocked) {
5759                        proc = mPidsSelfLocked.get(pid);
5760                    }
5761                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5762                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5763                                + " from background process " + proc);
5764                        return;
5765                    }
5766                }
5767                closeSystemDialogsLocked(reason);
5768            }
5769        } finally {
5770            Binder.restoreCallingIdentity(origId);
5771        }
5772    }
5773
5774    void closeSystemDialogsLocked(String reason) {
5775        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5776        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5777                | Intent.FLAG_RECEIVER_FOREGROUND);
5778        if (reason != null) {
5779            intent.putExtra("reason", reason);
5780        }
5781        mWindowManager.closeSystemDialogs(reason);
5782
5783        mStackSupervisor.closeSystemDialogsLocked();
5784
5785        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5786                AppOpsManager.OP_NONE, null, false, false,
5787                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5788    }
5789
5790    @Override
5791    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5792        enforceNotIsolatedCaller("getProcessMemoryInfo");
5793        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5794        for (int i=pids.length-1; i>=0; i--) {
5795            ProcessRecord proc;
5796            int oomAdj;
5797            synchronized (this) {
5798                synchronized (mPidsSelfLocked) {
5799                    proc = mPidsSelfLocked.get(pids[i]);
5800                    oomAdj = proc != null ? proc.setAdj : 0;
5801                }
5802            }
5803            infos[i] = new Debug.MemoryInfo();
5804            Debug.getMemoryInfo(pids[i], infos[i]);
5805            if (proc != null) {
5806                synchronized (this) {
5807                    if (proc.thread != null && proc.setAdj == oomAdj) {
5808                        // Record this for posterity if the process has been stable.
5809                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5810                                infos[i].getTotalUss(), false, proc.pkgList);
5811                    }
5812                }
5813            }
5814        }
5815        return infos;
5816    }
5817
5818    @Override
5819    public long[] getProcessPss(int[] pids) {
5820        enforceNotIsolatedCaller("getProcessPss");
5821        long[] pss = new long[pids.length];
5822        for (int i=pids.length-1; i>=0; i--) {
5823            ProcessRecord proc;
5824            int oomAdj;
5825            synchronized (this) {
5826                synchronized (mPidsSelfLocked) {
5827                    proc = mPidsSelfLocked.get(pids[i]);
5828                    oomAdj = proc != null ? proc.setAdj : 0;
5829                }
5830            }
5831            long[] tmpUss = new long[1];
5832            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5833            if (proc != null) {
5834                synchronized (this) {
5835                    if (proc.thread != null && proc.setAdj == oomAdj) {
5836                        // Record this for posterity if the process has been stable.
5837                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5838                    }
5839                }
5840            }
5841        }
5842        return pss;
5843    }
5844
5845    @Override
5846    public void killApplicationProcess(String processName, int uid) {
5847        if (processName == null) {
5848            return;
5849        }
5850
5851        int callerUid = Binder.getCallingUid();
5852        // Only the system server can kill an application
5853        if (callerUid == Process.SYSTEM_UID) {
5854            synchronized (this) {
5855                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5856                if (app != null && app.thread != null) {
5857                    try {
5858                        app.thread.scheduleSuicide();
5859                    } catch (RemoteException e) {
5860                        // If the other end already died, then our work here is done.
5861                    }
5862                } else {
5863                    Slog.w(TAG, "Process/uid not found attempting kill of "
5864                            + processName + " / " + uid);
5865                }
5866            }
5867        } else {
5868            throw new SecurityException(callerUid + " cannot kill app process: " +
5869                    processName);
5870        }
5871    }
5872
5873    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5874        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5875                false, true, false, false, UserHandle.getUserId(uid), reason);
5876    }
5877
5878    private void finishForceStopPackageLocked(final String packageName, int uid) {
5879        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5880                Uri.fromParts("package", packageName, null));
5881        if (!mProcessesReady) {
5882            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5883                    | Intent.FLAG_RECEIVER_FOREGROUND);
5884        }
5885        intent.putExtra(Intent.EXTRA_UID, uid);
5886        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5887        broadcastIntentLocked(null, null, intent,
5888                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5889                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5890    }
5891
5892
5893    private final boolean killPackageProcessesLocked(String packageName, int appId,
5894            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5895            boolean doit, boolean evenPersistent, String reason) {
5896        ArrayList<ProcessRecord> procs = new ArrayList<>();
5897
5898        // Remove all processes this package may have touched: all with the
5899        // same UID (except for the system or root user), and all whose name
5900        // matches the package name.
5901        final int NP = mProcessNames.getMap().size();
5902        for (int ip=0; ip<NP; ip++) {
5903            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5904            final int NA = apps.size();
5905            for (int ia=0; ia<NA; ia++) {
5906                ProcessRecord app = apps.valueAt(ia);
5907                if (app.persistent && !evenPersistent) {
5908                    // we don't kill persistent processes
5909                    continue;
5910                }
5911                if (app.removed) {
5912                    if (doit) {
5913                        procs.add(app);
5914                    }
5915                    continue;
5916                }
5917
5918                // Skip process if it doesn't meet our oom adj requirement.
5919                if (app.setAdj < minOomAdj) {
5920                    continue;
5921                }
5922
5923                // If no package is specified, we call all processes under the
5924                // give user id.
5925                if (packageName == null) {
5926                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5927                        continue;
5928                    }
5929                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5930                        continue;
5931                    }
5932                // Package has been specified, we want to hit all processes
5933                // that match it.  We need to qualify this by the processes
5934                // that are running under the specified app and user ID.
5935                } else {
5936                    final boolean isDep = app.pkgDeps != null
5937                            && app.pkgDeps.contains(packageName);
5938                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5939                        continue;
5940                    }
5941                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5942                        continue;
5943                    }
5944                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5945                        continue;
5946                    }
5947                }
5948
5949                // Process has passed all conditions, kill it!
5950                if (!doit) {
5951                    return true;
5952                }
5953                app.removed = true;
5954                procs.add(app);
5955            }
5956        }
5957
5958        int N = procs.size();
5959        for (int i=0; i<N; i++) {
5960            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5961        }
5962        updateOomAdjLocked();
5963        return N > 0;
5964    }
5965
5966    private void cleanupDisabledPackageComponentsLocked(
5967            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5968
5969        Set<String> disabledClasses = null;
5970        boolean packageDisabled = false;
5971        IPackageManager pm = AppGlobals.getPackageManager();
5972
5973        if (changedClasses == null) {
5974            // Nothing changed...
5975            return;
5976        }
5977
5978        // Determine enable/disable state of the package and its components.
5979        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5980        for (int i = changedClasses.length - 1; i >= 0; i--) {
5981            final String changedClass = changedClasses[i];
5982
5983            if (changedClass.equals(packageName)) {
5984                try {
5985                    // Entire package setting changed
5986                    enabled = pm.getApplicationEnabledSetting(packageName,
5987                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5988                } catch (Exception e) {
5989                    // No such package/component; probably racing with uninstall.  In any
5990                    // event it means we have nothing further to do here.
5991                    return;
5992                }
5993                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5994                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5995                if (packageDisabled) {
5996                    // Entire package is disabled.
5997                    // No need to continue to check component states.
5998                    disabledClasses = null;
5999                    break;
6000                }
6001            } else {
6002                try {
6003                    enabled = pm.getComponentEnabledSetting(
6004                            new ComponentName(packageName, changedClass),
6005                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6006                } catch (Exception e) {
6007                    // As above, probably racing with uninstall.
6008                    return;
6009                }
6010                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6011                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6012                    if (disabledClasses == null) {
6013                        disabledClasses = new ArraySet<>(changedClasses.length);
6014                    }
6015                    disabledClasses.add(changedClass);
6016                }
6017            }
6018        }
6019
6020        if (!packageDisabled && disabledClasses == null) {
6021            // Nothing to do here...
6022            return;
6023        }
6024
6025        // Clean-up disabled activities.
6026        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6027                packageName, disabledClasses, true, false, userId) && mBooted) {
6028            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6029            mStackSupervisor.scheduleIdleLocked();
6030        }
6031
6032        // Clean-up disabled tasks
6033        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6034
6035        // Clean-up disabled services.
6036        mServices.bringDownDisabledPackageServicesLocked(
6037                packageName, disabledClasses, userId, false, killProcess, true);
6038
6039        // Clean-up disabled providers.
6040        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6041        mProviderMap.collectPackageProvidersLocked(
6042                packageName, disabledClasses, true, false, userId, providers);
6043        for (int i = providers.size() - 1; i >= 0; i--) {
6044            removeDyingProviderLocked(null, providers.get(i), true);
6045        }
6046
6047        // Clean-up disabled broadcast receivers.
6048        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6049            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6050                    packageName, disabledClasses, userId, true);
6051        }
6052
6053    }
6054
6055    final boolean clearBroadcastQueueForUserLocked(int userId) {
6056        boolean didSomething = false;
6057        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6058            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6059                    null, null, userId, true);
6060        }
6061        return didSomething;
6062    }
6063
6064    final boolean forceStopPackageLocked(String packageName, int appId,
6065            boolean callerWillRestart, boolean purgeCache, boolean doit,
6066            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6067        int i;
6068
6069        if (userId == UserHandle.USER_ALL && packageName == null) {
6070            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6071        }
6072
6073        if (appId < 0 && packageName != null) {
6074            try {
6075                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6076                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6077            } catch (RemoteException e) {
6078            }
6079        }
6080
6081        if (doit) {
6082            if (packageName != null) {
6083                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6084                        + " user=" + userId + ": " + reason);
6085            } else {
6086                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6087            }
6088
6089            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6090        }
6091
6092        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6093                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6094                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6095
6096        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6097                packageName, null, doit, evenPersistent, userId)) {
6098            if (!doit) {
6099                return true;
6100            }
6101            didSomething = true;
6102        }
6103
6104        if (mServices.bringDownDisabledPackageServicesLocked(
6105                packageName, null, userId, evenPersistent, true, doit)) {
6106            if (!doit) {
6107                return true;
6108            }
6109            didSomething = true;
6110        }
6111
6112        if (packageName == null) {
6113            // Remove all sticky broadcasts from this user.
6114            mStickyBroadcasts.remove(userId);
6115        }
6116
6117        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6118        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6119                userId, providers)) {
6120            if (!doit) {
6121                return true;
6122            }
6123            didSomething = true;
6124        }
6125        for (i = providers.size() - 1; i >= 0; i--) {
6126            removeDyingProviderLocked(null, providers.get(i), true);
6127        }
6128
6129        // Remove transient permissions granted from/to this package/user
6130        removeUriPermissionsForPackageLocked(packageName, userId, false);
6131
6132        if (doit) {
6133            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6134                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6135                        packageName, null, userId, doit);
6136            }
6137        }
6138
6139        if (packageName == null || uninstalling) {
6140            // Remove pending intents.  For now we only do this when force
6141            // stopping users, because we have some problems when doing this
6142            // for packages -- app widgets are not currently cleaned up for
6143            // such packages, so they can be left with bad pending intents.
6144            if (mIntentSenderRecords.size() > 0) {
6145                Iterator<WeakReference<PendingIntentRecord>> it
6146                        = mIntentSenderRecords.values().iterator();
6147                while (it.hasNext()) {
6148                    WeakReference<PendingIntentRecord> wpir = it.next();
6149                    if (wpir == null) {
6150                        it.remove();
6151                        continue;
6152                    }
6153                    PendingIntentRecord pir = wpir.get();
6154                    if (pir == null) {
6155                        it.remove();
6156                        continue;
6157                    }
6158                    if (packageName == null) {
6159                        // Stopping user, remove all objects for the user.
6160                        if (pir.key.userId != userId) {
6161                            // Not the same user, skip it.
6162                            continue;
6163                        }
6164                    } else {
6165                        if (UserHandle.getAppId(pir.uid) != appId) {
6166                            // Different app id, skip it.
6167                            continue;
6168                        }
6169                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6170                            // Different user, skip it.
6171                            continue;
6172                        }
6173                        if (!pir.key.packageName.equals(packageName)) {
6174                            // Different package, skip it.
6175                            continue;
6176                        }
6177                    }
6178                    if (!doit) {
6179                        return true;
6180                    }
6181                    didSomething = true;
6182                    it.remove();
6183                    pir.canceled = true;
6184                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6185                        pir.key.activity.pendingResults.remove(pir.ref);
6186                    }
6187                }
6188            }
6189        }
6190
6191        if (doit) {
6192            if (purgeCache && packageName != null) {
6193                AttributeCache ac = AttributeCache.instance();
6194                if (ac != null) {
6195                    ac.removePackage(packageName);
6196                }
6197            }
6198            if (mBooted) {
6199                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6200                mStackSupervisor.scheduleIdleLocked();
6201            }
6202        }
6203
6204        return didSomething;
6205    }
6206
6207    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6208        ProcessRecord old = mProcessNames.remove(name, uid);
6209        if (old != null) {
6210            old.uidRecord.numProcs--;
6211            if (old.uidRecord.numProcs == 0) {
6212                // No more processes using this uid, tell clients it is gone.
6213                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6214                        "No more processes in " + old.uidRecord);
6215                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6216                mActiveUids.remove(uid);
6217                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6218            }
6219            old.uidRecord = null;
6220        }
6221        mIsolatedProcesses.remove(uid);
6222        return old;
6223    }
6224
6225    private final void addProcessNameLocked(ProcessRecord proc) {
6226        // We shouldn't already have a process under this name, but just in case we
6227        // need to clean up whatever may be there now.
6228        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6229        if (old == proc && proc.persistent) {
6230            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6231            Slog.w(TAG, "Re-adding persistent process " + proc);
6232        } else if (old != null) {
6233            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6234        }
6235        UidRecord uidRec = mActiveUids.get(proc.uid);
6236        if (uidRec == null) {
6237            uidRec = new UidRecord(proc.uid);
6238            // This is the first appearance of the uid, report it now!
6239            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6240                    "Creating new process uid: " + uidRec);
6241            mActiveUids.put(proc.uid, uidRec);
6242            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6243            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6244        }
6245        proc.uidRecord = uidRec;
6246        uidRec.numProcs++;
6247        mProcessNames.put(proc.processName, proc.uid, proc);
6248        if (proc.isolated) {
6249            mIsolatedProcesses.put(proc.uid, proc);
6250        }
6251    }
6252
6253    boolean removeProcessLocked(ProcessRecord app,
6254            boolean callerWillRestart, boolean allowRestart, String reason) {
6255        final String name = app.processName;
6256        final int uid = app.uid;
6257        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6258            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6259
6260        ProcessRecord old = mProcessNames.get(name, uid);
6261        if (old != app) {
6262            // This process is no longer active, so nothing to do.
6263            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6264            return false;
6265        }
6266        removeProcessNameLocked(name, uid);
6267        if (mHeavyWeightProcess == app) {
6268            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6269                    mHeavyWeightProcess.userId, 0));
6270            mHeavyWeightProcess = null;
6271        }
6272        boolean needRestart = false;
6273        if (app.pid > 0 && app.pid != MY_PID) {
6274            int pid = app.pid;
6275            synchronized (mPidsSelfLocked) {
6276                mPidsSelfLocked.remove(pid);
6277                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6278            }
6279            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6280            if (app.isolated) {
6281                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6282            }
6283            boolean willRestart = false;
6284            if (app.persistent && !app.isolated) {
6285                if (!callerWillRestart) {
6286                    willRestart = true;
6287                } else {
6288                    needRestart = true;
6289                }
6290            }
6291            app.kill(reason, true);
6292            handleAppDiedLocked(app, willRestart, allowRestart);
6293            if (willRestart) {
6294                removeLruProcessLocked(app);
6295                addAppLocked(app.info, false, null /* ABI override */);
6296            }
6297        } else {
6298            mRemovedProcesses.add(app);
6299        }
6300
6301        return needRestart;
6302    }
6303
6304    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6305        cleanupAppInLaunchingProvidersLocked(app, true);
6306        removeProcessLocked(app, false, true, "timeout publishing content providers");
6307    }
6308
6309    private final void processStartTimedOutLocked(ProcessRecord app) {
6310        final int pid = app.pid;
6311        boolean gone = false;
6312        synchronized (mPidsSelfLocked) {
6313            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6314            if (knownApp != null && knownApp.thread == null) {
6315                mPidsSelfLocked.remove(pid);
6316                gone = true;
6317            }
6318        }
6319
6320        if (gone) {
6321            Slog.w(TAG, "Process " + app + " failed to attach");
6322            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6323                    pid, app.uid, app.processName);
6324            removeProcessNameLocked(app.processName, app.uid);
6325            if (mHeavyWeightProcess == app) {
6326                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6327                        mHeavyWeightProcess.userId, 0));
6328                mHeavyWeightProcess = null;
6329            }
6330            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6331            if (app.isolated) {
6332                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6333            }
6334            // Take care of any launching providers waiting for this process.
6335            cleanupAppInLaunchingProvidersLocked(app, true);
6336            // Take care of any services that are waiting for the process.
6337            mServices.processStartTimedOutLocked(app);
6338            app.kill("start timeout", true);
6339            removeLruProcessLocked(app);
6340            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6341                Slog.w(TAG, "Unattached app died before backup, skipping");
6342                try {
6343                    IBackupManager bm = IBackupManager.Stub.asInterface(
6344                            ServiceManager.getService(Context.BACKUP_SERVICE));
6345                    bm.agentDisconnected(app.info.packageName);
6346                } catch (RemoteException e) {
6347                    // Can't happen; the backup manager is local
6348                }
6349            }
6350            if (isPendingBroadcastProcessLocked(pid)) {
6351                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6352                skipPendingBroadcastLocked(pid);
6353            }
6354        } else {
6355            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6356        }
6357    }
6358
6359    private final boolean attachApplicationLocked(IApplicationThread thread,
6360            int pid) {
6361
6362        // Find the application record that is being attached...  either via
6363        // the pid if we are running in multiple processes, or just pull the
6364        // next app record if we are emulating process with anonymous threads.
6365        ProcessRecord app;
6366        if (pid != MY_PID && pid >= 0) {
6367            synchronized (mPidsSelfLocked) {
6368                app = mPidsSelfLocked.get(pid);
6369            }
6370        } else {
6371            app = null;
6372        }
6373
6374        if (app == null) {
6375            Slog.w(TAG, "No pending application record for pid " + pid
6376                    + " (IApplicationThread " + thread + "); dropping process");
6377            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6378            if (pid > 0 && pid != MY_PID) {
6379                Process.killProcessQuiet(pid);
6380                //TODO: killProcessGroup(app.info.uid, pid);
6381            } else {
6382                try {
6383                    thread.scheduleExit();
6384                } catch (Exception e) {
6385                    // Ignore exceptions.
6386                }
6387            }
6388            return false;
6389        }
6390
6391        // If this application record is still attached to a previous
6392        // process, clean it up now.
6393        if (app.thread != null) {
6394            handleAppDiedLocked(app, true, true);
6395        }
6396
6397        // Tell the process all about itself.
6398
6399        if (DEBUG_ALL) Slog.v(
6400                TAG, "Binding process pid " + pid + " to record " + app);
6401
6402        final String processName = app.processName;
6403        try {
6404            AppDeathRecipient adr = new AppDeathRecipient(
6405                    app, pid, thread);
6406            thread.asBinder().linkToDeath(adr, 0);
6407            app.deathRecipient = adr;
6408        } catch (RemoteException e) {
6409            app.resetPackageList(mProcessStats);
6410            startProcessLocked(app, "link fail", processName);
6411            return false;
6412        }
6413
6414        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6415
6416        app.makeActive(thread, mProcessStats);
6417        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6418        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6419        app.forcingToForeground = null;
6420        updateProcessForegroundLocked(app, false, false);
6421        app.hasShownUi = false;
6422        app.debugging = false;
6423        app.cached = false;
6424        app.killedByAm = false;
6425
6426        // We carefully use the same state that PackageManager uses for
6427        // filtering, since we use this flag to decide if we need to install
6428        // providers when user is unlocked later
6429        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6430
6431        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6432
6433        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6434        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6435
6436        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6437            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6438            msg.obj = app;
6439            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6440        }
6441
6442        if (!normalMode) {
6443            Slog.i(TAG, "Launching preboot mode app: " + app);
6444        }
6445
6446        if (DEBUG_ALL) Slog.v(
6447            TAG, "New app record " + app
6448            + " thread=" + thread.asBinder() + " pid=" + pid);
6449        try {
6450            int testMode = IApplicationThread.DEBUG_OFF;
6451            if (mDebugApp != null && mDebugApp.equals(processName)) {
6452                testMode = mWaitForDebugger
6453                    ? IApplicationThread.DEBUG_WAIT
6454                    : IApplicationThread.DEBUG_ON;
6455                app.debugging = true;
6456                if (mDebugTransient) {
6457                    mDebugApp = mOrigDebugApp;
6458                    mWaitForDebugger = mOrigWaitForDebugger;
6459                }
6460            }
6461            String profileFile = app.instrumentationProfileFile;
6462            ParcelFileDescriptor profileFd = null;
6463            int samplingInterval = 0;
6464            boolean profileAutoStop = false;
6465            if (mProfileApp != null && mProfileApp.equals(processName)) {
6466                mProfileProc = app;
6467                profileFile = mProfileFile;
6468                profileFd = mProfileFd;
6469                samplingInterval = mSamplingInterval;
6470                profileAutoStop = mAutoStopProfiler;
6471            }
6472            boolean enableTrackAllocation = false;
6473            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6474                enableTrackAllocation = true;
6475                mTrackAllocationApp = null;
6476            }
6477
6478            // If the app is being launched for restore or full backup, set it up specially
6479            boolean isRestrictedBackupMode = false;
6480            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6481                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6482                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6483                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6484                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6485            }
6486
6487            if (app.instrumentationClass != null) {
6488                notifyPackageUse(app.instrumentationClass.getPackageName(),
6489                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6490            }
6491            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6492                    + processName + " with config " + mConfiguration);
6493            ApplicationInfo appInfo = app.instrumentationInfo != null
6494                    ? app.instrumentationInfo : app.info;
6495            app.compat = compatibilityInfoForPackageLocked(appInfo);
6496            if (profileFd != null) {
6497                profileFd = profileFd.dup();
6498            }
6499            ProfilerInfo profilerInfo = profileFile == null ? null
6500                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6501            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6502                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6503                    app.instrumentationUiAutomationConnection, testMode,
6504                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6505                    isRestrictedBackupMode || !normalMode, app.persistent,
6506                    new Configuration(mConfiguration), app.compat,
6507                    getCommonServicesLocked(app.isolated),
6508                    mCoreSettingsObserver.getCoreSettingsLocked());
6509            updateLruProcessLocked(app, false, null);
6510            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6511        } catch (Exception e) {
6512            // todo: Yikes!  What should we do?  For now we will try to
6513            // start another process, but that could easily get us in
6514            // an infinite loop of restarting processes...
6515            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6516
6517            app.resetPackageList(mProcessStats);
6518            app.unlinkDeathRecipient();
6519            startProcessLocked(app, "bind fail", processName);
6520            return false;
6521        }
6522
6523        // Remove this record from the list of starting applications.
6524        mPersistentStartingProcesses.remove(app);
6525        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6526                "Attach application locked removing on hold: " + app);
6527        mProcessesOnHold.remove(app);
6528
6529        boolean badApp = false;
6530        boolean didSomething = false;
6531
6532        // See if the top visible activity is waiting to run in this process...
6533        if (normalMode) {
6534            try {
6535                if (mStackSupervisor.attachApplicationLocked(app)) {
6536                    didSomething = true;
6537                }
6538            } catch (Exception e) {
6539                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6540                badApp = true;
6541            }
6542        }
6543
6544        // Find any services that should be running in this process...
6545        if (!badApp) {
6546            try {
6547                didSomething |= mServices.attachApplicationLocked(app, processName);
6548            } catch (Exception e) {
6549                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6550                badApp = true;
6551            }
6552        }
6553
6554        // Check if a next-broadcast receiver is in this process...
6555        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6556            try {
6557                didSomething |= sendPendingBroadcastsLocked(app);
6558            } catch (Exception e) {
6559                // If the app died trying to launch the receiver we declare it 'bad'
6560                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6561                badApp = true;
6562            }
6563        }
6564
6565        // Check whether the next backup agent is in this process...
6566        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6567            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6568                    "New app is backup target, launching agent for " + app);
6569            notifyPackageUse(mBackupTarget.appInfo.packageName,
6570                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6571            try {
6572                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6573                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6574                        mBackupTarget.backupMode);
6575            } catch (Exception e) {
6576                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6577                badApp = true;
6578            }
6579        }
6580
6581        if (badApp) {
6582            app.kill("error during init", true);
6583            handleAppDiedLocked(app, false, true);
6584            return false;
6585        }
6586
6587        if (!didSomething) {
6588            updateOomAdjLocked();
6589        }
6590
6591        return true;
6592    }
6593
6594    @Override
6595    public final void attachApplication(IApplicationThread thread) {
6596        synchronized (this) {
6597            int callingPid = Binder.getCallingPid();
6598            final long origId = Binder.clearCallingIdentity();
6599            attachApplicationLocked(thread, callingPid);
6600            Binder.restoreCallingIdentity(origId);
6601        }
6602    }
6603
6604    @Override
6605    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6606        final long origId = Binder.clearCallingIdentity();
6607        synchronized (this) {
6608            ActivityStack stack = ActivityRecord.getStackLocked(token);
6609            if (stack != null) {
6610                ActivityRecord r =
6611                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6612                if (stopProfiling) {
6613                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6614                        try {
6615                            mProfileFd.close();
6616                        } catch (IOException e) {
6617                        }
6618                        clearProfilerLocked();
6619                    }
6620                }
6621            }
6622        }
6623        Binder.restoreCallingIdentity(origId);
6624    }
6625
6626    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6627        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6628                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6629    }
6630
6631    void enableScreenAfterBoot() {
6632        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6633                SystemClock.uptimeMillis());
6634        mWindowManager.enableScreenAfterBoot();
6635
6636        synchronized (this) {
6637            updateEventDispatchingLocked();
6638        }
6639    }
6640
6641    @Override
6642    public void showBootMessage(final CharSequence msg, final boolean always) {
6643        if (Binder.getCallingUid() != Process.myUid()) {
6644            // These days only the core system can call this, so apps can't get in
6645            // the way of what we show about running them.
6646        }
6647        mWindowManager.showBootMessage(msg, always);
6648    }
6649
6650    @Override
6651    public void keyguardWaitingForActivityDrawn() {
6652        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6653        final long token = Binder.clearCallingIdentity();
6654        try {
6655            synchronized (this) {
6656                if (DEBUG_LOCKSCREEN) logLockScreen("");
6657                mWindowManager.keyguardWaitingForActivityDrawn();
6658                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6659                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6660                    updateSleepIfNeededLocked();
6661                }
6662            }
6663        } finally {
6664            Binder.restoreCallingIdentity(token);
6665        }
6666    }
6667
6668    @Override
6669    public void keyguardGoingAway(int flags) {
6670        enforceNotIsolatedCaller("keyguardGoingAway");
6671        final long token = Binder.clearCallingIdentity();
6672        try {
6673            synchronized (this) {
6674                if (DEBUG_LOCKSCREEN) logLockScreen("");
6675                mWindowManager.keyguardGoingAway(flags);
6676                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6677                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6678                    updateSleepIfNeededLocked();
6679
6680                    // Some stack visibility might change (e.g. docked stack)
6681                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6682                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6683                }
6684            }
6685        } finally {
6686            Binder.restoreCallingIdentity(token);
6687        }
6688    }
6689
6690    final void finishBooting() {
6691        synchronized (this) {
6692            if (!mBootAnimationComplete) {
6693                mCallFinishBooting = true;
6694                return;
6695            }
6696            mCallFinishBooting = false;
6697        }
6698
6699        ArraySet<String> completedIsas = new ArraySet<String>();
6700        for (String abi : Build.SUPPORTED_ABIS) {
6701            Process.establishZygoteConnectionForAbi(abi);
6702            final String instructionSet = VMRuntime.getInstructionSet(abi);
6703            if (!completedIsas.contains(instructionSet)) {
6704                try {
6705                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6706                } catch (InstallerException e) {
6707                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6708                            e.getMessage() +")");
6709                }
6710                completedIsas.add(instructionSet);
6711            }
6712        }
6713
6714        IntentFilter pkgFilter = new IntentFilter();
6715        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6716        pkgFilter.addDataScheme("package");
6717        mContext.registerReceiver(new BroadcastReceiver() {
6718            @Override
6719            public void onReceive(Context context, Intent intent) {
6720                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6721                if (pkgs != null) {
6722                    for (String pkg : pkgs) {
6723                        synchronized (ActivityManagerService.this) {
6724                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6725                                    0, "query restart")) {
6726                                setResultCode(Activity.RESULT_OK);
6727                                return;
6728                            }
6729                        }
6730                    }
6731                }
6732            }
6733        }, pkgFilter);
6734
6735        IntentFilter dumpheapFilter = new IntentFilter();
6736        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6737        mContext.registerReceiver(new BroadcastReceiver() {
6738            @Override
6739            public void onReceive(Context context, Intent intent) {
6740                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6741                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6742                } else {
6743                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6744                }
6745            }
6746        }, dumpheapFilter);
6747
6748        // Let system services know.
6749        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6750
6751        synchronized (this) {
6752            // Ensure that any processes we had put on hold are now started
6753            // up.
6754            final int NP = mProcessesOnHold.size();
6755            if (NP > 0) {
6756                ArrayList<ProcessRecord> procs =
6757                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6758                for (int ip=0; ip<NP; ip++) {
6759                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6760                            + procs.get(ip));
6761                    startProcessLocked(procs.get(ip), "on-hold", null);
6762                }
6763            }
6764
6765            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6766                // Start looking for apps that are abusing wake locks.
6767                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6768                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6769                // Tell anyone interested that we are done booting!
6770                SystemProperties.set("sys.boot_completed", "1");
6771
6772                // And trigger dev.bootcomplete if we are not showing encryption progress
6773                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6774                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6775                    SystemProperties.set("dev.bootcomplete", "1");
6776                }
6777                mUserController.sendBootCompletedLocked(
6778                        new IIntentReceiver.Stub() {
6779                            @Override
6780                            public void performReceive(Intent intent, int resultCode,
6781                                    String data, Bundle extras, boolean ordered,
6782                                    boolean sticky, int sendingUser) {
6783                                synchronized (ActivityManagerService.this) {
6784                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6785                                            true, false);
6786                                }
6787                            }
6788                        });
6789                scheduleStartProfilesLocked();
6790            }
6791        }
6792    }
6793
6794    @Override
6795    public void bootAnimationComplete() {
6796        final boolean callFinishBooting;
6797        synchronized (this) {
6798            callFinishBooting = mCallFinishBooting;
6799            mBootAnimationComplete = true;
6800        }
6801        if (callFinishBooting) {
6802            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6803            finishBooting();
6804            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6805        }
6806    }
6807
6808    final void ensureBootCompleted() {
6809        boolean booting;
6810        boolean enableScreen;
6811        synchronized (this) {
6812            booting = mBooting;
6813            mBooting = false;
6814            enableScreen = !mBooted;
6815            mBooted = true;
6816        }
6817
6818        if (booting) {
6819            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6820            finishBooting();
6821            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6822        }
6823
6824        if (enableScreen) {
6825            enableScreenAfterBoot();
6826        }
6827    }
6828
6829    @Override
6830    public final void activityResumed(IBinder token) {
6831        final long origId = Binder.clearCallingIdentity();
6832        synchronized(this) {
6833            ActivityStack stack = ActivityRecord.getStackLocked(token);
6834            if (stack != null) {
6835                stack.activityResumedLocked(token);
6836            }
6837        }
6838        Binder.restoreCallingIdentity(origId);
6839    }
6840
6841    @Override
6842    public final void activityPaused(IBinder token) {
6843        final long origId = Binder.clearCallingIdentity();
6844        synchronized(this) {
6845            ActivityStack stack = ActivityRecord.getStackLocked(token);
6846            if (stack != null) {
6847                stack.activityPausedLocked(token, false);
6848            }
6849        }
6850        Binder.restoreCallingIdentity(origId);
6851    }
6852
6853    @Override
6854    public final void activityStopped(IBinder token, Bundle icicle,
6855            PersistableBundle persistentState, CharSequence description) {
6856        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6857
6858        // Refuse possible leaked file descriptors
6859        if (icicle != null && icicle.hasFileDescriptors()) {
6860            throw new IllegalArgumentException("File descriptors passed in Bundle");
6861        }
6862
6863        final long origId = Binder.clearCallingIdentity();
6864
6865        synchronized (this) {
6866            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6867            if (r != null) {
6868                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6869            }
6870        }
6871
6872        trimApplications();
6873
6874        Binder.restoreCallingIdentity(origId);
6875    }
6876
6877    @Override
6878    public final void activityDestroyed(IBinder token) {
6879        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6880        synchronized (this) {
6881            ActivityStack stack = ActivityRecord.getStackLocked(token);
6882            if (stack != null) {
6883                stack.activityDestroyedLocked(token, "activityDestroyed");
6884            }
6885        }
6886    }
6887
6888    @Override
6889    public final void activityRelaunched(IBinder token) {
6890        final long origId = Binder.clearCallingIdentity();
6891        synchronized (this) {
6892            mStackSupervisor.activityRelaunchedLocked(token);
6893        }
6894        Binder.restoreCallingIdentity(origId);
6895    }
6896
6897    @Override
6898    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6899            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6900        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6901                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6902        synchronized (this) {
6903            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6904            if (record == null) {
6905                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6906                        + "found for: " + token);
6907            }
6908            record.setSizeConfigurations(horizontalSizeConfiguration,
6909                    verticalSizeConfigurations, smallestSizeConfigurations);
6910        }
6911    }
6912
6913    @Override
6914    public final void backgroundResourcesReleased(IBinder token) {
6915        final long origId = Binder.clearCallingIdentity();
6916        try {
6917            synchronized (this) {
6918                ActivityStack stack = ActivityRecord.getStackLocked(token);
6919                if (stack != null) {
6920                    stack.backgroundResourcesReleased();
6921                }
6922            }
6923        } finally {
6924            Binder.restoreCallingIdentity(origId);
6925        }
6926    }
6927
6928    @Override
6929    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6930        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6931    }
6932
6933    @Override
6934    public final void notifyEnterAnimationComplete(IBinder token) {
6935        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6936    }
6937
6938    @Override
6939    public String getCallingPackage(IBinder token) {
6940        synchronized (this) {
6941            ActivityRecord r = getCallingRecordLocked(token);
6942            return r != null ? r.info.packageName : null;
6943        }
6944    }
6945
6946    @Override
6947    public ComponentName getCallingActivity(IBinder token) {
6948        synchronized (this) {
6949            ActivityRecord r = getCallingRecordLocked(token);
6950            return r != null ? r.intent.getComponent() : null;
6951        }
6952    }
6953
6954    private ActivityRecord getCallingRecordLocked(IBinder token) {
6955        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6956        if (r == null) {
6957            return null;
6958        }
6959        return r.resultTo;
6960    }
6961
6962    @Override
6963    public ComponentName getActivityClassForToken(IBinder token) {
6964        synchronized(this) {
6965            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6966            if (r == null) {
6967                return null;
6968            }
6969            return r.intent.getComponent();
6970        }
6971    }
6972
6973    @Override
6974    public String getPackageForToken(IBinder token) {
6975        synchronized(this) {
6976            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6977            if (r == null) {
6978                return null;
6979            }
6980            return r.packageName;
6981        }
6982    }
6983
6984    @Override
6985    public boolean isRootVoiceInteraction(IBinder token) {
6986        synchronized(this) {
6987            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6988            if (r == null) {
6989                return false;
6990            }
6991            return r.rootVoiceInteraction;
6992        }
6993    }
6994
6995    @Override
6996    public IIntentSender getIntentSender(int type,
6997            String packageName, IBinder token, String resultWho,
6998            int requestCode, Intent[] intents, String[] resolvedTypes,
6999            int flags, Bundle bOptions, int userId) {
7000        enforceNotIsolatedCaller("getIntentSender");
7001        // Refuse possible leaked file descriptors
7002        if (intents != null) {
7003            if (intents.length < 1) {
7004                throw new IllegalArgumentException("Intents array length must be >= 1");
7005            }
7006            for (int i=0; i<intents.length; i++) {
7007                Intent intent = intents[i];
7008                if (intent != null) {
7009                    if (intent.hasFileDescriptors()) {
7010                        throw new IllegalArgumentException("File descriptors passed in Intent");
7011                    }
7012                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7013                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7014                        throw new IllegalArgumentException(
7015                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7016                    }
7017                    intents[i] = new Intent(intent);
7018                }
7019            }
7020            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7021                throw new IllegalArgumentException(
7022                        "Intent array length does not match resolvedTypes length");
7023            }
7024        }
7025        if (bOptions != null) {
7026            if (bOptions.hasFileDescriptors()) {
7027                throw new IllegalArgumentException("File descriptors passed in options");
7028            }
7029        }
7030
7031        synchronized(this) {
7032            int callingUid = Binder.getCallingUid();
7033            int origUserId = userId;
7034            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7035                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7036                    ALLOW_NON_FULL, "getIntentSender", null);
7037            if (origUserId == UserHandle.USER_CURRENT) {
7038                // We don't want to evaluate this until the pending intent is
7039                // actually executed.  However, we do want to always do the
7040                // security checking for it above.
7041                userId = UserHandle.USER_CURRENT;
7042            }
7043            try {
7044                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7045                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7046                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7047                    if (!UserHandle.isSameApp(callingUid, uid)) {
7048                        String msg = "Permission Denial: getIntentSender() from pid="
7049                            + Binder.getCallingPid()
7050                            + ", uid=" + Binder.getCallingUid()
7051                            + ", (need uid=" + uid + ")"
7052                            + " is not allowed to send as package " + packageName;
7053                        Slog.w(TAG, msg);
7054                        throw new SecurityException(msg);
7055                    }
7056                }
7057
7058                return getIntentSenderLocked(type, packageName, callingUid, userId,
7059                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7060
7061            } catch (RemoteException e) {
7062                throw new SecurityException(e);
7063            }
7064        }
7065    }
7066
7067    IIntentSender getIntentSenderLocked(int type, String packageName,
7068            int callingUid, int userId, IBinder token, String resultWho,
7069            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7070            Bundle bOptions) {
7071        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7072        ActivityRecord activity = null;
7073        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7074            activity = ActivityRecord.isInStackLocked(token);
7075            if (activity == null) {
7076                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7077                return null;
7078            }
7079            if (activity.finishing) {
7080                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7081                return null;
7082            }
7083        }
7084
7085        // We're going to be splicing together extras before sending, so we're
7086        // okay poking into any contained extras.
7087        if (intents != null) {
7088            for (int i = 0; i < intents.length; i++) {
7089                intents[i].setDefusable(true);
7090            }
7091        }
7092        Bundle.setDefusable(bOptions, true);
7093
7094        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7095        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7096        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7097        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7098                |PendingIntent.FLAG_UPDATE_CURRENT);
7099
7100        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7101                type, packageName, activity, resultWho,
7102                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7103        WeakReference<PendingIntentRecord> ref;
7104        ref = mIntentSenderRecords.get(key);
7105        PendingIntentRecord rec = ref != null ? ref.get() : null;
7106        if (rec != null) {
7107            if (!cancelCurrent) {
7108                if (updateCurrent) {
7109                    if (rec.key.requestIntent != null) {
7110                        rec.key.requestIntent.replaceExtras(intents != null ?
7111                                intents[intents.length - 1] : null);
7112                    }
7113                    if (intents != null) {
7114                        intents[intents.length-1] = rec.key.requestIntent;
7115                        rec.key.allIntents = intents;
7116                        rec.key.allResolvedTypes = resolvedTypes;
7117                    } else {
7118                        rec.key.allIntents = null;
7119                        rec.key.allResolvedTypes = null;
7120                    }
7121                }
7122                return rec;
7123            }
7124            rec.canceled = true;
7125            mIntentSenderRecords.remove(key);
7126        }
7127        if (noCreate) {
7128            return rec;
7129        }
7130        rec = new PendingIntentRecord(this, key, callingUid);
7131        mIntentSenderRecords.put(key, rec.ref);
7132        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7133            if (activity.pendingResults == null) {
7134                activity.pendingResults
7135                        = new HashSet<WeakReference<PendingIntentRecord>>();
7136            }
7137            activity.pendingResults.add(rec.ref);
7138        }
7139        return rec;
7140    }
7141
7142    @Override
7143    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7144            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7145        if (target instanceof PendingIntentRecord) {
7146            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7147                    finishedReceiver, requiredPermission, options);
7148        } else {
7149            if (intent == null) {
7150                // Weird case: someone has given us their own custom IIntentSender, and now
7151                // they have someone else trying to send to it but of course this isn't
7152                // really a PendingIntent, so there is no base Intent, and the caller isn't
7153                // supplying an Intent... but we never want to dispatch a null Intent to
7154                // a receiver, so um...  let's make something up.
7155                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7156                intent = new Intent(Intent.ACTION_MAIN);
7157            }
7158            try {
7159                target.send(code, intent, resolvedType, null, requiredPermission, options);
7160            } catch (RemoteException e) {
7161            }
7162            // Platform code can rely on getting a result back when the send is done, but if
7163            // this intent sender is from outside of the system we can't rely on it doing that.
7164            // So instead we don't give it the result receiver, and instead just directly
7165            // report the finish immediately.
7166            if (finishedReceiver != null) {
7167                try {
7168                    finishedReceiver.performReceive(intent, 0,
7169                            null, null, false, false, UserHandle.getCallingUserId());
7170                } catch (RemoteException e) {
7171                }
7172            }
7173            return 0;
7174        }
7175    }
7176
7177    /**
7178     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7179     *
7180     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7181     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7182     */
7183    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7184        if (DEBUG_WHITELISTS) {
7185            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7186                    + targetUid + ", " + duration + ")");
7187        }
7188        synchronized (mPidsSelfLocked) {
7189            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7190            if (pr == null) {
7191                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7192                return;
7193            }
7194            if (!pr.whitelistManager) {
7195                if (DEBUG_WHITELISTS) {
7196                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7197                            + callerPid + " is not allowed");
7198                }
7199                return;
7200            }
7201        }
7202
7203        final long token = Binder.clearCallingIdentity();
7204        try {
7205            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7206                    true, "pe from uid:" + callerUid);
7207        } finally {
7208            Binder.restoreCallingIdentity(token);
7209        }
7210    }
7211
7212    @Override
7213    public void cancelIntentSender(IIntentSender sender) {
7214        if (!(sender instanceof PendingIntentRecord)) {
7215            return;
7216        }
7217        synchronized(this) {
7218            PendingIntentRecord rec = (PendingIntentRecord)sender;
7219            try {
7220                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7221                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7222                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7223                    String msg = "Permission Denial: cancelIntentSender() from pid="
7224                        + Binder.getCallingPid()
7225                        + ", uid=" + Binder.getCallingUid()
7226                        + " is not allowed to cancel packges "
7227                        + rec.key.packageName;
7228                    Slog.w(TAG, msg);
7229                    throw new SecurityException(msg);
7230                }
7231            } catch (RemoteException e) {
7232                throw new SecurityException(e);
7233            }
7234            cancelIntentSenderLocked(rec, true);
7235        }
7236    }
7237
7238    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7239        rec.canceled = true;
7240        mIntentSenderRecords.remove(rec.key);
7241        if (cleanActivity && rec.key.activity != null) {
7242            rec.key.activity.pendingResults.remove(rec.ref);
7243        }
7244    }
7245
7246    @Override
7247    public String getPackageForIntentSender(IIntentSender pendingResult) {
7248        if (!(pendingResult instanceof PendingIntentRecord)) {
7249            return null;
7250        }
7251        try {
7252            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7253            return res.key.packageName;
7254        } catch (ClassCastException e) {
7255        }
7256        return null;
7257    }
7258
7259    @Override
7260    public int getUidForIntentSender(IIntentSender sender) {
7261        if (sender instanceof PendingIntentRecord) {
7262            try {
7263                PendingIntentRecord res = (PendingIntentRecord)sender;
7264                return res.uid;
7265            } catch (ClassCastException e) {
7266            }
7267        }
7268        return -1;
7269    }
7270
7271    @Override
7272    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7273        if (!(pendingResult instanceof PendingIntentRecord)) {
7274            return false;
7275        }
7276        try {
7277            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7278            if (res.key.allIntents == null) {
7279                return false;
7280            }
7281            for (int i=0; i<res.key.allIntents.length; i++) {
7282                Intent intent = res.key.allIntents[i];
7283                if (intent.getPackage() != null && intent.getComponent() != null) {
7284                    return false;
7285                }
7286            }
7287            return true;
7288        } catch (ClassCastException e) {
7289        }
7290        return false;
7291    }
7292
7293    @Override
7294    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7295        if (!(pendingResult instanceof PendingIntentRecord)) {
7296            return false;
7297        }
7298        try {
7299            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7300            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7301                return true;
7302            }
7303            return false;
7304        } catch (ClassCastException e) {
7305        }
7306        return false;
7307    }
7308
7309    @Override
7310    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7311        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7312                "getIntentForIntentSender()");
7313        if (!(pendingResult instanceof PendingIntentRecord)) {
7314            return null;
7315        }
7316        try {
7317            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7318            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7319        } catch (ClassCastException e) {
7320        }
7321        return null;
7322    }
7323
7324    @Override
7325    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7326        if (!(pendingResult instanceof PendingIntentRecord)) {
7327            return null;
7328        }
7329        try {
7330            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7331            synchronized (this) {
7332                return getTagForIntentSenderLocked(res, prefix);
7333            }
7334        } catch (ClassCastException e) {
7335        }
7336        return null;
7337    }
7338
7339    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7340        final Intent intent = res.key.requestIntent;
7341        if (intent != null) {
7342            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7343                    || res.lastTagPrefix.equals(prefix))) {
7344                return res.lastTag;
7345            }
7346            res.lastTagPrefix = prefix;
7347            final StringBuilder sb = new StringBuilder(128);
7348            if (prefix != null) {
7349                sb.append(prefix);
7350            }
7351            if (intent.getAction() != null) {
7352                sb.append(intent.getAction());
7353            } else if (intent.getComponent() != null) {
7354                intent.getComponent().appendShortString(sb);
7355            } else {
7356                sb.append("?");
7357            }
7358            return res.lastTag = sb.toString();
7359        }
7360        return null;
7361    }
7362
7363    @Override
7364    public void setProcessLimit(int max) {
7365        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7366                "setProcessLimit()");
7367        synchronized (this) {
7368            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7369            mProcessLimitOverride = max;
7370        }
7371        trimApplications();
7372    }
7373
7374    @Override
7375    public int getProcessLimit() {
7376        synchronized (this) {
7377            return mProcessLimitOverride;
7378        }
7379    }
7380
7381    void foregroundTokenDied(ForegroundToken token) {
7382        synchronized (ActivityManagerService.this) {
7383            synchronized (mPidsSelfLocked) {
7384                ForegroundToken cur
7385                    = mForegroundProcesses.get(token.pid);
7386                if (cur != token) {
7387                    return;
7388                }
7389                mForegroundProcesses.remove(token.pid);
7390                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7391                if (pr == null) {
7392                    return;
7393                }
7394                pr.forcingToForeground = null;
7395                updateProcessForegroundLocked(pr, false, false);
7396            }
7397            updateOomAdjLocked();
7398        }
7399    }
7400
7401    @Override
7402    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7403        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7404                "setProcessForeground()");
7405        synchronized(this) {
7406            boolean changed = false;
7407
7408            synchronized (mPidsSelfLocked) {
7409                ProcessRecord pr = mPidsSelfLocked.get(pid);
7410                if (pr == null && isForeground) {
7411                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7412                    return;
7413                }
7414                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7415                if (oldToken != null) {
7416                    oldToken.token.unlinkToDeath(oldToken, 0);
7417                    mForegroundProcesses.remove(pid);
7418                    if (pr != null) {
7419                        pr.forcingToForeground = null;
7420                    }
7421                    changed = true;
7422                }
7423                if (isForeground && token != null) {
7424                    ForegroundToken newToken = new ForegroundToken() {
7425                        @Override
7426                        public void binderDied() {
7427                            foregroundTokenDied(this);
7428                        }
7429                    };
7430                    newToken.pid = pid;
7431                    newToken.token = token;
7432                    try {
7433                        token.linkToDeath(newToken, 0);
7434                        mForegroundProcesses.put(pid, newToken);
7435                        pr.forcingToForeground = token;
7436                        changed = true;
7437                    } catch (RemoteException e) {
7438                        // If the process died while doing this, we will later
7439                        // do the cleanup with the process death link.
7440                    }
7441                }
7442            }
7443
7444            if (changed) {
7445                updateOomAdjLocked();
7446            }
7447        }
7448    }
7449
7450    @Override
7451    public boolean isAppForeground(int uid) throws RemoteException {
7452        synchronized (this) {
7453            UidRecord uidRec = mActiveUids.get(uid);
7454            if (uidRec == null || uidRec.idle) {
7455                return false;
7456            }
7457            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7458        }
7459    }
7460
7461    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7462    // be guarded by permission checking.
7463    int getUidState(int uid) {
7464        synchronized (this) {
7465            UidRecord uidRec = mActiveUids.get(uid);
7466            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7467        }
7468    }
7469
7470    @Override
7471    public boolean isInMultiWindowMode(IBinder token) {
7472        final long origId = Binder.clearCallingIdentity();
7473        try {
7474            synchronized(this) {
7475                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7476                if (r == null) {
7477                    return false;
7478                }
7479                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7480                return !r.task.mFullscreen;
7481            }
7482        } finally {
7483            Binder.restoreCallingIdentity(origId);
7484        }
7485    }
7486
7487    @Override
7488    public boolean isInPictureInPictureMode(IBinder token) {
7489        final long origId = Binder.clearCallingIdentity();
7490        try {
7491            synchronized(this) {
7492                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7493                if (stack == null) {
7494                    return false;
7495                }
7496                return stack.mStackId == PINNED_STACK_ID;
7497            }
7498        } finally {
7499            Binder.restoreCallingIdentity(origId);
7500        }
7501    }
7502
7503    @Override
7504    public void enterPictureInPictureMode(IBinder token) {
7505        final long origId = Binder.clearCallingIdentity();
7506        try {
7507            synchronized(this) {
7508                if (!mSupportsPictureInPicture) {
7509                    throw new IllegalStateException("enterPictureInPictureMode: "
7510                            + "Device doesn't support picture-in-picture mode.");
7511                }
7512
7513                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7514
7515                if (r == null) {
7516                    throw new IllegalStateException("enterPictureInPictureMode: "
7517                            + "Can't find activity for token=" + token);
7518                }
7519
7520                if (!r.supportsPictureInPicture()) {
7521                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7522                            + "Picture-In-Picture not supported for r=" + r);
7523                }
7524
7525                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7526                // current bounds.
7527                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7528                final Rect bounds = (pinnedStack != null)
7529                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7530
7531                mStackSupervisor.moveActivityToPinnedStackLocked(
7532                        r, "enterPictureInPictureMode", bounds);
7533            }
7534        } finally {
7535            Binder.restoreCallingIdentity(origId);
7536        }
7537    }
7538
7539    // =========================================================
7540    // PROCESS INFO
7541    // =========================================================
7542
7543    static class ProcessInfoService extends IProcessInfoService.Stub {
7544        final ActivityManagerService mActivityManagerService;
7545        ProcessInfoService(ActivityManagerService activityManagerService) {
7546            mActivityManagerService = activityManagerService;
7547        }
7548
7549        @Override
7550        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7551            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7552                    /*in*/ pids, /*out*/ states, null);
7553        }
7554
7555        @Override
7556        public void getProcessStatesAndOomScoresFromPids(
7557                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7558            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7559                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7560        }
7561    }
7562
7563    /**
7564     * For each PID in the given input array, write the current process state
7565     * for that process into the states array, or -1 to indicate that no
7566     * process with the given PID exists. If scores array is provided, write
7567     * the oom score for the process into the scores array, with INVALID_ADJ
7568     * indicating the PID doesn't exist.
7569     */
7570    public void getProcessStatesAndOomScoresForPIDs(
7571            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7572        if (scores != null) {
7573            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7574                    "getProcessStatesAndOomScoresForPIDs()");
7575        }
7576
7577        if (pids == null) {
7578            throw new NullPointerException("pids");
7579        } else if (states == null) {
7580            throw new NullPointerException("states");
7581        } else if (pids.length != states.length) {
7582            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7583        } else if (scores != null && pids.length != scores.length) {
7584            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7585        }
7586
7587        synchronized (mPidsSelfLocked) {
7588            for (int i = 0; i < pids.length; i++) {
7589                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7590                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7591                        pr.curProcState;
7592                if (scores != null) {
7593                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7594                }
7595            }
7596        }
7597    }
7598
7599    // =========================================================
7600    // PERMISSIONS
7601    // =========================================================
7602
7603    static class PermissionController extends IPermissionController.Stub {
7604        ActivityManagerService mActivityManagerService;
7605        PermissionController(ActivityManagerService activityManagerService) {
7606            mActivityManagerService = activityManagerService;
7607        }
7608
7609        @Override
7610        public boolean checkPermission(String permission, int pid, int uid) {
7611            return mActivityManagerService.checkPermission(permission, pid,
7612                    uid) == PackageManager.PERMISSION_GRANTED;
7613        }
7614
7615        @Override
7616        public String[] getPackagesForUid(int uid) {
7617            return mActivityManagerService.mContext.getPackageManager()
7618                    .getPackagesForUid(uid);
7619        }
7620
7621        @Override
7622        public boolean isRuntimePermission(String permission) {
7623            try {
7624                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7625                        .getPermissionInfo(permission, 0);
7626                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7627            } catch (NameNotFoundException nnfe) {
7628                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7629            }
7630            return false;
7631        }
7632    }
7633
7634    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7635        @Override
7636        public int checkComponentPermission(String permission, int pid, int uid,
7637                int owningUid, boolean exported) {
7638            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7639                    owningUid, exported);
7640        }
7641
7642        @Override
7643        public Object getAMSLock() {
7644            return ActivityManagerService.this;
7645        }
7646    }
7647
7648    /**
7649     * This can be called with or without the global lock held.
7650     */
7651    int checkComponentPermission(String permission, int pid, int uid,
7652            int owningUid, boolean exported) {
7653        if (pid == MY_PID) {
7654            return PackageManager.PERMISSION_GRANTED;
7655        }
7656        return ActivityManager.checkComponentPermission(permission, uid,
7657                owningUid, exported);
7658    }
7659
7660    /**
7661     * As the only public entry point for permissions checking, this method
7662     * can enforce the semantic that requesting a check on a null global
7663     * permission is automatically denied.  (Internally a null permission
7664     * string is used when calling {@link #checkComponentPermission} in cases
7665     * when only uid-based security is needed.)
7666     *
7667     * This can be called with or without the global lock held.
7668     */
7669    @Override
7670    public int checkPermission(String permission, int pid, int uid) {
7671        if (permission == null) {
7672            return PackageManager.PERMISSION_DENIED;
7673        }
7674        return checkComponentPermission(permission, pid, uid, -1, true);
7675    }
7676
7677    @Override
7678    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7679        if (permission == null) {
7680            return PackageManager.PERMISSION_DENIED;
7681        }
7682
7683        // We might be performing an operation on behalf of an indirect binder
7684        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7685        // client identity accordingly before proceeding.
7686        Identity tlsIdentity = sCallerIdentity.get();
7687        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7688            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7689                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7690            uid = tlsIdentity.uid;
7691            pid = tlsIdentity.pid;
7692        }
7693
7694        return checkComponentPermission(permission, pid, uid, -1, true);
7695    }
7696
7697    /**
7698     * Binder IPC calls go through the public entry point.
7699     * This can be called with or without the global lock held.
7700     */
7701    int checkCallingPermission(String permission) {
7702        return checkPermission(permission,
7703                Binder.getCallingPid(),
7704                UserHandle.getAppId(Binder.getCallingUid()));
7705    }
7706
7707    /**
7708     * This can be called with or without the global lock held.
7709     */
7710    void enforceCallingPermission(String permission, String func) {
7711        if (checkCallingPermission(permission)
7712                == PackageManager.PERMISSION_GRANTED) {
7713            return;
7714        }
7715
7716        String msg = "Permission Denial: " + func + " from pid="
7717                + Binder.getCallingPid()
7718                + ", uid=" + Binder.getCallingUid()
7719                + " requires " + permission;
7720        Slog.w(TAG, msg);
7721        throw new SecurityException(msg);
7722    }
7723
7724    /**
7725     * Determine if UID is holding permissions required to access {@link Uri} in
7726     * the given {@link ProviderInfo}. Final permission checking is always done
7727     * in {@link ContentProvider}.
7728     */
7729    private final boolean checkHoldingPermissionsLocked(
7730            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7731        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7732                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7733        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7734            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7735                    != PERMISSION_GRANTED) {
7736                return false;
7737            }
7738        }
7739        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7740    }
7741
7742    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7743            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7744        if (pi.applicationInfo.uid == uid) {
7745            return true;
7746        } else if (!pi.exported) {
7747            return false;
7748        }
7749
7750        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7751        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7752        try {
7753            // check if target holds top-level <provider> permissions
7754            if (!readMet && pi.readPermission != null && considerUidPermissions
7755                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7756                readMet = true;
7757            }
7758            if (!writeMet && pi.writePermission != null && considerUidPermissions
7759                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7760                writeMet = true;
7761            }
7762
7763            // track if unprotected read/write is allowed; any denied
7764            // <path-permission> below removes this ability
7765            boolean allowDefaultRead = pi.readPermission == null;
7766            boolean allowDefaultWrite = pi.writePermission == null;
7767
7768            // check if target holds any <path-permission> that match uri
7769            final PathPermission[] pps = pi.pathPermissions;
7770            if (pps != null) {
7771                final String path = grantUri.uri.getPath();
7772                int i = pps.length;
7773                while (i > 0 && (!readMet || !writeMet)) {
7774                    i--;
7775                    PathPermission pp = pps[i];
7776                    if (pp.match(path)) {
7777                        if (!readMet) {
7778                            final String pprperm = pp.getReadPermission();
7779                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7780                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7781                                    + ": match=" + pp.match(path)
7782                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7783                            if (pprperm != null) {
7784                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7785                                        == PERMISSION_GRANTED) {
7786                                    readMet = true;
7787                                } else {
7788                                    allowDefaultRead = false;
7789                                }
7790                            }
7791                        }
7792                        if (!writeMet) {
7793                            final String ppwperm = pp.getWritePermission();
7794                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7795                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7796                                    + ": match=" + pp.match(path)
7797                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7798                            if (ppwperm != null) {
7799                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7800                                        == PERMISSION_GRANTED) {
7801                                    writeMet = true;
7802                                } else {
7803                                    allowDefaultWrite = false;
7804                                }
7805                            }
7806                        }
7807                    }
7808                }
7809            }
7810
7811            // grant unprotected <provider> read/write, if not blocked by
7812            // <path-permission> above
7813            if (allowDefaultRead) readMet = true;
7814            if (allowDefaultWrite) writeMet = true;
7815
7816        } catch (RemoteException e) {
7817            return false;
7818        }
7819
7820        return readMet && writeMet;
7821    }
7822
7823    public int getAppStartMode(int uid, String packageName) {
7824        synchronized (this) {
7825            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7826        }
7827    }
7828
7829    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7830            boolean allowWhenForeground) {
7831        UidRecord uidRec = mActiveUids.get(uid);
7832        if (!mLenientBackgroundCheck) {
7833            if (!allowWhenForeground || uidRec == null
7834                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7835                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7836                        packageName) != AppOpsManager.MODE_ALLOWED) {
7837                    return ActivityManager.APP_START_MODE_DELAYED;
7838                }
7839            }
7840
7841        } else if (uidRec == null || uidRec.idle) {
7842            if (callingPid >= 0) {
7843                ProcessRecord proc;
7844                synchronized (mPidsSelfLocked) {
7845                    proc = mPidsSelfLocked.get(callingPid);
7846                }
7847                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7848                    // Whoever is instigating this is in the foreground, so we will allow it
7849                    // to go through.
7850                    return ActivityManager.APP_START_MODE_NORMAL;
7851                }
7852            }
7853            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7854                    != AppOpsManager.MODE_ALLOWED) {
7855                return ActivityManager.APP_START_MODE_DELAYED;
7856            }
7857        }
7858        return ActivityManager.APP_START_MODE_NORMAL;
7859    }
7860
7861    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7862        ProviderInfo pi = null;
7863        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7864        if (cpr != null) {
7865            pi = cpr.info;
7866        } else {
7867            try {
7868                pi = AppGlobals.getPackageManager().resolveContentProvider(
7869                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7870                        userHandle);
7871            } catch (RemoteException ex) {
7872            }
7873        }
7874        return pi;
7875    }
7876
7877    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7878        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7879        if (targetUris != null) {
7880            return targetUris.get(grantUri);
7881        }
7882        return null;
7883    }
7884
7885    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7886            String targetPkg, int targetUid, GrantUri grantUri) {
7887        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7888        if (targetUris == null) {
7889            targetUris = Maps.newArrayMap();
7890            mGrantedUriPermissions.put(targetUid, targetUris);
7891        }
7892
7893        UriPermission perm = targetUris.get(grantUri);
7894        if (perm == null) {
7895            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7896            targetUris.put(grantUri, perm);
7897        }
7898
7899        return perm;
7900    }
7901
7902    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7903            final int modeFlags) {
7904        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7905        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7906                : UriPermission.STRENGTH_OWNED;
7907
7908        // Root gets to do everything.
7909        if (uid == 0) {
7910            return true;
7911        }
7912
7913        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7914        if (perms == null) return false;
7915
7916        // First look for exact match
7917        final UriPermission exactPerm = perms.get(grantUri);
7918        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7919            return true;
7920        }
7921
7922        // No exact match, look for prefixes
7923        final int N = perms.size();
7924        for (int i = 0; i < N; i++) {
7925            final UriPermission perm = perms.valueAt(i);
7926            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7927                    && perm.getStrength(modeFlags) >= minStrength) {
7928                return true;
7929            }
7930        }
7931
7932        return false;
7933    }
7934
7935    /**
7936     * @param uri This uri must NOT contain an embedded userId.
7937     * @param userId The userId in which the uri is to be resolved.
7938     */
7939    @Override
7940    public int checkUriPermission(Uri uri, int pid, int uid,
7941            final int modeFlags, int userId, IBinder callerToken) {
7942        enforceNotIsolatedCaller("checkUriPermission");
7943
7944        // Another redirected-binder-call permissions check as in
7945        // {@link checkPermissionWithToken}.
7946        Identity tlsIdentity = sCallerIdentity.get();
7947        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7948            uid = tlsIdentity.uid;
7949            pid = tlsIdentity.pid;
7950        }
7951
7952        // Our own process gets to do everything.
7953        if (pid == MY_PID) {
7954            return PackageManager.PERMISSION_GRANTED;
7955        }
7956        synchronized (this) {
7957            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7958                    ? PackageManager.PERMISSION_GRANTED
7959                    : PackageManager.PERMISSION_DENIED;
7960        }
7961    }
7962
7963    /**
7964     * Check if the targetPkg can be granted permission to access uri by
7965     * the callingUid using the given modeFlags.  Throws a security exception
7966     * if callingUid is not allowed to do this.  Returns the uid of the target
7967     * if the URI permission grant should be performed; returns -1 if it is not
7968     * needed (for example targetPkg already has permission to access the URI).
7969     * If you already know the uid of the target, you can supply it in
7970     * lastTargetUid else set that to -1.
7971     */
7972    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7973            final int modeFlags, int lastTargetUid) {
7974        if (!Intent.isAccessUriMode(modeFlags)) {
7975            return -1;
7976        }
7977
7978        if (targetPkg != null) {
7979            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7980                    "Checking grant " + targetPkg + " permission to " + grantUri);
7981        }
7982
7983        final IPackageManager pm = AppGlobals.getPackageManager();
7984
7985        // If this is not a content: uri, we can't do anything with it.
7986        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7987            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7988                    "Can't grant URI permission for non-content URI: " + grantUri);
7989            return -1;
7990        }
7991
7992        final String authority = grantUri.uri.getAuthority();
7993        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7994                MATCH_DEBUG_TRIAGED_MISSING);
7995        if (pi == null) {
7996            Slog.w(TAG, "No content provider found for permission check: " +
7997                    grantUri.uri.toSafeString());
7998            return -1;
7999        }
8000
8001        int targetUid = lastTargetUid;
8002        if (targetUid < 0 && targetPkg != null) {
8003            try {
8004                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8005                        UserHandle.getUserId(callingUid));
8006                if (targetUid < 0) {
8007                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8008                            "Can't grant URI permission no uid for: " + targetPkg);
8009                    return -1;
8010                }
8011            } catch (RemoteException ex) {
8012                return -1;
8013            }
8014        }
8015
8016        if (targetUid >= 0) {
8017            // First...  does the target actually need this permission?
8018            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8019                // No need to grant the target this permission.
8020                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8021                        "Target " + targetPkg + " already has full permission to " + grantUri);
8022                return -1;
8023            }
8024        } else {
8025            // First...  there is no target package, so can anyone access it?
8026            boolean allowed = pi.exported;
8027            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8028                if (pi.readPermission != null) {
8029                    allowed = false;
8030                }
8031            }
8032            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8033                if (pi.writePermission != null) {
8034                    allowed = false;
8035                }
8036            }
8037            if (allowed) {
8038                return -1;
8039            }
8040        }
8041
8042        /* There is a special cross user grant if:
8043         * - The target is on another user.
8044         * - Apps on the current user can access the uri without any uid permissions.
8045         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8046         * grant uri permissions.
8047         */
8048        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8049                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8050                modeFlags, false /*without considering the uid permissions*/);
8051
8052        // Second...  is the provider allowing granting of URI permissions?
8053        if (!specialCrossUserGrant) {
8054            if (!pi.grantUriPermissions) {
8055                throw new SecurityException("Provider " + pi.packageName
8056                        + "/" + pi.name
8057                        + " does not allow granting of Uri permissions (uri "
8058                        + grantUri + ")");
8059            }
8060            if (pi.uriPermissionPatterns != null) {
8061                final int N = pi.uriPermissionPatterns.length;
8062                boolean allowed = false;
8063                for (int i=0; i<N; i++) {
8064                    if (pi.uriPermissionPatterns[i] != null
8065                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8066                        allowed = true;
8067                        break;
8068                    }
8069                }
8070                if (!allowed) {
8071                    throw new SecurityException("Provider " + pi.packageName
8072                            + "/" + pi.name
8073                            + " does not allow granting of permission to path of Uri "
8074                            + grantUri);
8075                }
8076            }
8077        }
8078
8079        // Third...  does the caller itself have permission to access
8080        // this uri?
8081        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8082            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8083                // Require they hold a strong enough Uri permission
8084                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8085                    throw new SecurityException("Uid " + callingUid
8086                            + " does not have permission to uri " + grantUri);
8087                }
8088            }
8089        }
8090        return targetUid;
8091    }
8092
8093    /**
8094     * @param uri This uri must NOT contain an embedded userId.
8095     * @param userId The userId in which the uri is to be resolved.
8096     */
8097    @Override
8098    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8099            final int modeFlags, int userId) {
8100        enforceNotIsolatedCaller("checkGrantUriPermission");
8101        synchronized(this) {
8102            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8103                    new GrantUri(userId, uri, false), modeFlags, -1);
8104        }
8105    }
8106
8107    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8108            final int modeFlags, UriPermissionOwner owner) {
8109        if (!Intent.isAccessUriMode(modeFlags)) {
8110            return;
8111        }
8112
8113        // So here we are: the caller has the assumed permission
8114        // to the uri, and the target doesn't.  Let's now give this to
8115        // the target.
8116
8117        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8118                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8119
8120        final String authority = grantUri.uri.getAuthority();
8121        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8122                MATCH_DEBUG_TRIAGED_MISSING);
8123        if (pi == null) {
8124            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8125            return;
8126        }
8127
8128        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8129            grantUri.prefix = true;
8130        }
8131        final UriPermission perm = findOrCreateUriPermissionLocked(
8132                pi.packageName, targetPkg, targetUid, grantUri);
8133        perm.grantModes(modeFlags, owner);
8134    }
8135
8136    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8137            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8138        if (targetPkg == null) {
8139            throw new NullPointerException("targetPkg");
8140        }
8141        int targetUid;
8142        final IPackageManager pm = AppGlobals.getPackageManager();
8143        try {
8144            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8145        } catch (RemoteException ex) {
8146            return;
8147        }
8148
8149        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8150                targetUid);
8151        if (targetUid < 0) {
8152            return;
8153        }
8154
8155        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8156                owner);
8157    }
8158
8159    static class NeededUriGrants extends ArrayList<GrantUri> {
8160        final String targetPkg;
8161        final int targetUid;
8162        final int flags;
8163
8164        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8165            this.targetPkg = targetPkg;
8166            this.targetUid = targetUid;
8167            this.flags = flags;
8168        }
8169    }
8170
8171    /**
8172     * Like checkGrantUriPermissionLocked, but takes an Intent.
8173     */
8174    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8175            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8176        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8177                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8178                + " clip=" + (intent != null ? intent.getClipData() : null)
8179                + " from " + intent + "; flags=0x"
8180                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8181
8182        if (targetPkg == null) {
8183            throw new NullPointerException("targetPkg");
8184        }
8185
8186        if (intent == null) {
8187            return null;
8188        }
8189        Uri data = intent.getData();
8190        ClipData clip = intent.getClipData();
8191        if (data == null && clip == null) {
8192            return null;
8193        }
8194        // Default userId for uris in the intent (if they don't specify it themselves)
8195        int contentUserHint = intent.getContentUserHint();
8196        if (contentUserHint == UserHandle.USER_CURRENT) {
8197            contentUserHint = UserHandle.getUserId(callingUid);
8198        }
8199        final IPackageManager pm = AppGlobals.getPackageManager();
8200        int targetUid;
8201        if (needed != null) {
8202            targetUid = needed.targetUid;
8203        } else {
8204            try {
8205                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8206                        targetUserId);
8207            } catch (RemoteException ex) {
8208                return null;
8209            }
8210            if (targetUid < 0) {
8211                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8212                        "Can't grant URI permission no uid for: " + targetPkg
8213                        + " on user " + targetUserId);
8214                return null;
8215            }
8216        }
8217        if (data != null) {
8218            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8219            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8220                    targetUid);
8221            if (targetUid > 0) {
8222                if (needed == null) {
8223                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8224                }
8225                needed.add(grantUri);
8226            }
8227        }
8228        if (clip != null) {
8229            for (int i=0; i<clip.getItemCount(); i++) {
8230                Uri uri = clip.getItemAt(i).getUri();
8231                if (uri != null) {
8232                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8233                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8234                            targetUid);
8235                    if (targetUid > 0) {
8236                        if (needed == null) {
8237                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8238                        }
8239                        needed.add(grantUri);
8240                    }
8241                } else {
8242                    Intent clipIntent = clip.getItemAt(i).getIntent();
8243                    if (clipIntent != null) {
8244                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8245                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8246                        if (newNeeded != null) {
8247                            needed = newNeeded;
8248                        }
8249                    }
8250                }
8251            }
8252        }
8253
8254        return needed;
8255    }
8256
8257    /**
8258     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8259     */
8260    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8261            UriPermissionOwner owner) {
8262        if (needed != null) {
8263            for (int i=0; i<needed.size(); i++) {
8264                GrantUri grantUri = needed.get(i);
8265                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8266                        grantUri, needed.flags, owner);
8267            }
8268        }
8269    }
8270
8271    void grantUriPermissionFromIntentLocked(int callingUid,
8272            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8273        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8274                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8275        if (needed == null) {
8276            return;
8277        }
8278
8279        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8280    }
8281
8282    /**
8283     * @param uri This uri must NOT contain an embedded userId.
8284     * @param userId The userId in which the uri is to be resolved.
8285     */
8286    @Override
8287    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8288            final int modeFlags, int userId) {
8289        enforceNotIsolatedCaller("grantUriPermission");
8290        GrantUri grantUri = new GrantUri(userId, uri, false);
8291        synchronized(this) {
8292            final ProcessRecord r = getRecordForAppLocked(caller);
8293            if (r == null) {
8294                throw new SecurityException("Unable to find app for caller "
8295                        + caller
8296                        + " when granting permission to uri " + grantUri);
8297            }
8298            if (targetPkg == null) {
8299                throw new IllegalArgumentException("null target");
8300            }
8301            if (grantUri == null) {
8302                throw new IllegalArgumentException("null uri");
8303            }
8304
8305            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8306                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8307                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8308                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8309
8310            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8311                    UserHandle.getUserId(r.uid));
8312        }
8313    }
8314
8315    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8316        if (perm.modeFlags == 0) {
8317            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8318                    perm.targetUid);
8319            if (perms != null) {
8320                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8321                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8322
8323                perms.remove(perm.uri);
8324                if (perms.isEmpty()) {
8325                    mGrantedUriPermissions.remove(perm.targetUid);
8326                }
8327            }
8328        }
8329    }
8330
8331    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8332        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8333                "Revoking all granted permissions to " + grantUri);
8334
8335        final IPackageManager pm = AppGlobals.getPackageManager();
8336        final String authority = grantUri.uri.getAuthority();
8337        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8338                MATCH_DEBUG_TRIAGED_MISSING);
8339        if (pi == null) {
8340            Slog.w(TAG, "No content provider found for permission revoke: "
8341                    + grantUri.toSafeString());
8342            return;
8343        }
8344
8345        // Does the caller have this permission on the URI?
8346        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8347            // If they don't have direct access to the URI, then revoke any
8348            // ownerless URI permissions that have been granted to them.
8349            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8350            if (perms != null) {
8351                boolean persistChanged = false;
8352                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8353                    final UriPermission perm = it.next();
8354                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8355                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8356                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8357                                "Revoking non-owned " + perm.targetUid
8358                                + " permission to " + perm.uri);
8359                        persistChanged |= perm.revokeModes(
8360                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8361                        if (perm.modeFlags == 0) {
8362                            it.remove();
8363                        }
8364                    }
8365                }
8366                if (perms.isEmpty()) {
8367                    mGrantedUriPermissions.remove(callingUid);
8368                }
8369                if (persistChanged) {
8370                    schedulePersistUriGrants();
8371                }
8372            }
8373            return;
8374        }
8375
8376        boolean persistChanged = false;
8377
8378        // Go through all of the permissions and remove any that match.
8379        int N = mGrantedUriPermissions.size();
8380        for (int i = 0; i < N; i++) {
8381            final int targetUid = mGrantedUriPermissions.keyAt(i);
8382            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8383
8384            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8385                final UriPermission perm = it.next();
8386                if (perm.uri.sourceUserId == grantUri.sourceUserId
8387                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8388                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8389                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8390                    persistChanged |= perm.revokeModes(
8391                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8392                    if (perm.modeFlags == 0) {
8393                        it.remove();
8394                    }
8395                }
8396            }
8397
8398            if (perms.isEmpty()) {
8399                mGrantedUriPermissions.remove(targetUid);
8400                N--;
8401                i--;
8402            }
8403        }
8404
8405        if (persistChanged) {
8406            schedulePersistUriGrants();
8407        }
8408    }
8409
8410    /**
8411     * @param uri This uri must NOT contain an embedded userId.
8412     * @param userId The userId in which the uri is to be resolved.
8413     */
8414    @Override
8415    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8416            int userId) {
8417        enforceNotIsolatedCaller("revokeUriPermission");
8418        synchronized(this) {
8419            final ProcessRecord r = getRecordForAppLocked(caller);
8420            if (r == null) {
8421                throw new SecurityException("Unable to find app for caller "
8422                        + caller
8423                        + " when revoking permission to uri " + uri);
8424            }
8425            if (uri == null) {
8426                Slog.w(TAG, "revokeUriPermission: null uri");
8427                return;
8428            }
8429
8430            if (!Intent.isAccessUriMode(modeFlags)) {
8431                return;
8432            }
8433
8434            final String authority = uri.getAuthority();
8435            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8436                    MATCH_DEBUG_TRIAGED_MISSING);
8437            if (pi == null) {
8438                Slog.w(TAG, "No content provider found for permission revoke: "
8439                        + uri.toSafeString());
8440                return;
8441            }
8442
8443            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8444        }
8445    }
8446
8447    /**
8448     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8449     * given package.
8450     *
8451     * @param packageName Package name to match, or {@code null} to apply to all
8452     *            packages.
8453     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8454     *            to all users.
8455     * @param persistable If persistable grants should be removed.
8456     */
8457    private void removeUriPermissionsForPackageLocked(
8458            String packageName, int userHandle, boolean persistable) {
8459        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8460            throw new IllegalArgumentException("Must narrow by either package or user");
8461        }
8462
8463        boolean persistChanged = false;
8464
8465        int N = mGrantedUriPermissions.size();
8466        for (int i = 0; i < N; i++) {
8467            final int targetUid = mGrantedUriPermissions.keyAt(i);
8468            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8469
8470            // Only inspect grants matching user
8471            if (userHandle == UserHandle.USER_ALL
8472                    || userHandle == UserHandle.getUserId(targetUid)) {
8473                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8474                    final UriPermission perm = it.next();
8475
8476                    // Only inspect grants matching package
8477                    if (packageName == null || perm.sourcePkg.equals(packageName)
8478                            || perm.targetPkg.equals(packageName)) {
8479                        persistChanged |= perm.revokeModes(persistable
8480                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8481
8482                        // Only remove when no modes remain; any persisted grants
8483                        // will keep this alive.
8484                        if (perm.modeFlags == 0) {
8485                            it.remove();
8486                        }
8487                    }
8488                }
8489
8490                if (perms.isEmpty()) {
8491                    mGrantedUriPermissions.remove(targetUid);
8492                    N--;
8493                    i--;
8494                }
8495            }
8496        }
8497
8498        if (persistChanged) {
8499            schedulePersistUriGrants();
8500        }
8501    }
8502
8503    @Override
8504    public IBinder newUriPermissionOwner(String name) {
8505        enforceNotIsolatedCaller("newUriPermissionOwner");
8506        synchronized(this) {
8507            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8508            return owner.getExternalTokenLocked();
8509        }
8510    }
8511
8512    @Override
8513    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8514        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8515        synchronized(this) {
8516            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8517            if (r == null) {
8518                throw new IllegalArgumentException("Activity does not exist; token="
8519                        + activityToken);
8520            }
8521            return r.getUriPermissionsLocked().getExternalTokenLocked();
8522        }
8523    }
8524    /**
8525     * @param uri This uri must NOT contain an embedded userId.
8526     * @param sourceUserId The userId in which the uri is to be resolved.
8527     * @param targetUserId The userId of the app that receives the grant.
8528     */
8529    @Override
8530    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8531            final int modeFlags, int sourceUserId, int targetUserId) {
8532        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8533                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8534                "grantUriPermissionFromOwner", null);
8535        synchronized(this) {
8536            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8537            if (owner == null) {
8538                throw new IllegalArgumentException("Unknown owner: " + token);
8539            }
8540            if (fromUid != Binder.getCallingUid()) {
8541                if (Binder.getCallingUid() != Process.myUid()) {
8542                    // Only system code can grant URI permissions on behalf
8543                    // of other users.
8544                    throw new SecurityException("nice try");
8545                }
8546            }
8547            if (targetPkg == null) {
8548                throw new IllegalArgumentException("null target");
8549            }
8550            if (uri == null) {
8551                throw new IllegalArgumentException("null uri");
8552            }
8553
8554            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8555                    modeFlags, owner, targetUserId);
8556        }
8557    }
8558
8559    /**
8560     * @param uri This uri must NOT contain an embedded userId.
8561     * @param userId The userId in which the uri is to be resolved.
8562     */
8563    @Override
8564    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8565        synchronized(this) {
8566            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8567            if (owner == null) {
8568                throw new IllegalArgumentException("Unknown owner: " + token);
8569            }
8570
8571            if (uri == null) {
8572                owner.removeUriPermissionsLocked(mode);
8573            } else {
8574                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8575            }
8576        }
8577    }
8578
8579    private void schedulePersistUriGrants() {
8580        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8581            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8582                    10 * DateUtils.SECOND_IN_MILLIS);
8583        }
8584    }
8585
8586    private void writeGrantedUriPermissions() {
8587        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8588
8589        // Snapshot permissions so we can persist without lock
8590        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8591        synchronized (this) {
8592            final int size = mGrantedUriPermissions.size();
8593            for (int i = 0; i < size; i++) {
8594                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8595                for (UriPermission perm : perms.values()) {
8596                    if (perm.persistedModeFlags != 0) {
8597                        persist.add(perm.snapshot());
8598                    }
8599                }
8600            }
8601        }
8602
8603        FileOutputStream fos = null;
8604        try {
8605            fos = mGrantFile.startWrite();
8606
8607            XmlSerializer out = new FastXmlSerializer();
8608            out.setOutput(fos, StandardCharsets.UTF_8.name());
8609            out.startDocument(null, true);
8610            out.startTag(null, TAG_URI_GRANTS);
8611            for (UriPermission.Snapshot perm : persist) {
8612                out.startTag(null, TAG_URI_GRANT);
8613                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8614                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8615                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8616                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8617                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8618                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8619                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8620                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8621                out.endTag(null, TAG_URI_GRANT);
8622            }
8623            out.endTag(null, TAG_URI_GRANTS);
8624            out.endDocument();
8625
8626            mGrantFile.finishWrite(fos);
8627        } catch (IOException e) {
8628            if (fos != null) {
8629                mGrantFile.failWrite(fos);
8630            }
8631        }
8632    }
8633
8634    private void readGrantedUriPermissionsLocked() {
8635        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8636
8637        final long now = System.currentTimeMillis();
8638
8639        FileInputStream fis = null;
8640        try {
8641            fis = mGrantFile.openRead();
8642            final XmlPullParser in = Xml.newPullParser();
8643            in.setInput(fis, StandardCharsets.UTF_8.name());
8644
8645            int type;
8646            while ((type = in.next()) != END_DOCUMENT) {
8647                final String tag = in.getName();
8648                if (type == START_TAG) {
8649                    if (TAG_URI_GRANT.equals(tag)) {
8650                        final int sourceUserId;
8651                        final int targetUserId;
8652                        final int userHandle = readIntAttribute(in,
8653                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8654                        if (userHandle != UserHandle.USER_NULL) {
8655                            // For backwards compatibility.
8656                            sourceUserId = userHandle;
8657                            targetUserId = userHandle;
8658                        } else {
8659                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8660                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8661                        }
8662                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8663                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8664                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8665                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8666                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8667                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8668
8669                        // Sanity check that provider still belongs to source package
8670                        // Both direct boot aware and unaware packages are fine as we
8671                        // will do filtering at query time to avoid multiple parsing.
8672                        final ProviderInfo pi = getProviderInfoLocked(
8673                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8674                                        | MATCH_DIRECT_BOOT_UNAWARE);
8675                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8676                            int targetUid = -1;
8677                            try {
8678                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8679                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8680                            } catch (RemoteException e) {
8681                            }
8682                            if (targetUid != -1) {
8683                                final UriPermission perm = findOrCreateUriPermissionLocked(
8684                                        sourcePkg, targetPkg, targetUid,
8685                                        new GrantUri(sourceUserId, uri, prefix));
8686                                perm.initPersistedModes(modeFlags, createdTime);
8687                            }
8688                        } else {
8689                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8690                                    + " but instead found " + pi);
8691                        }
8692                    }
8693                }
8694            }
8695        } catch (FileNotFoundException e) {
8696            // Missing grants is okay
8697        } catch (IOException e) {
8698            Slog.wtf(TAG, "Failed reading Uri grants", e);
8699        } catch (XmlPullParserException e) {
8700            Slog.wtf(TAG, "Failed reading Uri grants", e);
8701        } finally {
8702            IoUtils.closeQuietly(fis);
8703        }
8704    }
8705
8706    /**
8707     * @param uri This uri must NOT contain an embedded userId.
8708     * @param userId The userId in which the uri is to be resolved.
8709     */
8710    @Override
8711    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8712        enforceNotIsolatedCaller("takePersistableUriPermission");
8713
8714        Preconditions.checkFlagsArgument(modeFlags,
8715                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8716
8717        synchronized (this) {
8718            final int callingUid = Binder.getCallingUid();
8719            boolean persistChanged = false;
8720            GrantUri grantUri = new GrantUri(userId, uri, false);
8721
8722            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8723                    new GrantUri(userId, uri, false));
8724            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8725                    new GrantUri(userId, uri, true));
8726
8727            final boolean exactValid = (exactPerm != null)
8728                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8729            final boolean prefixValid = (prefixPerm != null)
8730                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8731
8732            if (!(exactValid || prefixValid)) {
8733                throw new SecurityException("No persistable permission grants found for UID "
8734                        + callingUid + " and Uri " + grantUri.toSafeString());
8735            }
8736
8737            if (exactValid) {
8738                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8739            }
8740            if (prefixValid) {
8741                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8742            }
8743
8744            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8745
8746            if (persistChanged) {
8747                schedulePersistUriGrants();
8748            }
8749        }
8750    }
8751
8752    /**
8753     * @param uri This uri must NOT contain an embedded userId.
8754     * @param userId The userId in which the uri is to be resolved.
8755     */
8756    @Override
8757    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8758        enforceNotIsolatedCaller("releasePersistableUriPermission");
8759
8760        Preconditions.checkFlagsArgument(modeFlags,
8761                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8762
8763        synchronized (this) {
8764            final int callingUid = Binder.getCallingUid();
8765            boolean persistChanged = false;
8766
8767            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8768                    new GrantUri(userId, uri, false));
8769            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8770                    new GrantUri(userId, uri, true));
8771            if (exactPerm == null && prefixPerm == null) {
8772                throw new SecurityException("No permission grants found for UID " + callingUid
8773                        + " and Uri " + uri.toSafeString());
8774            }
8775
8776            if (exactPerm != null) {
8777                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8778                removeUriPermissionIfNeededLocked(exactPerm);
8779            }
8780            if (prefixPerm != null) {
8781                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8782                removeUriPermissionIfNeededLocked(prefixPerm);
8783            }
8784
8785            if (persistChanged) {
8786                schedulePersistUriGrants();
8787            }
8788        }
8789    }
8790
8791    /**
8792     * Prune any older {@link UriPermission} for the given UID until outstanding
8793     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8794     *
8795     * @return if any mutations occured that require persisting.
8796     */
8797    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8798        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8799        if (perms == null) return false;
8800        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8801
8802        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8803        for (UriPermission perm : perms.values()) {
8804            if (perm.persistedModeFlags != 0) {
8805                persisted.add(perm);
8806            }
8807        }
8808
8809        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8810        if (trimCount <= 0) return false;
8811
8812        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8813        for (int i = 0; i < trimCount; i++) {
8814            final UriPermission perm = persisted.get(i);
8815
8816            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8817                    "Trimming grant created at " + perm.persistedCreateTime);
8818
8819            perm.releasePersistableModes(~0);
8820            removeUriPermissionIfNeededLocked(perm);
8821        }
8822
8823        return true;
8824    }
8825
8826    @Override
8827    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8828            String packageName, boolean incoming) {
8829        enforceNotIsolatedCaller("getPersistedUriPermissions");
8830        Preconditions.checkNotNull(packageName, "packageName");
8831
8832        final int callingUid = Binder.getCallingUid();
8833        final IPackageManager pm = AppGlobals.getPackageManager();
8834        try {
8835            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8836                    UserHandle.getUserId(callingUid));
8837            if (packageUid != callingUid) {
8838                throw new SecurityException(
8839                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8840            }
8841        } catch (RemoteException e) {
8842            throw new SecurityException("Failed to verify package name ownership");
8843        }
8844
8845        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8846        synchronized (this) {
8847            if (incoming) {
8848                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8849                        callingUid);
8850                if (perms == null) {
8851                    Slog.w(TAG, "No permission grants found for " + packageName);
8852                } else {
8853                    final int userId = UserHandle.getUserId(callingUid);
8854                    Set<String> existingAuthorities = null;
8855
8856                    for (UriPermission perm : perms.values()) {
8857                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8858                            // Is this provider available in the current boot state? If the user
8859                            // is not running and unlocked we check if the provider package exists.
8860                            if (!mUserController.isUserRunningLocked(userId,
8861                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8862                                String authority = perm.uri.uri.getAuthority();
8863                                if (existingAuthorities == null
8864                                        || !existingAuthorities.contains(authority)) {
8865                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8866                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8867                                    if (providerInfo != null) {
8868                                        if (existingAuthorities == null) {
8869                                            existingAuthorities = new ArraySet<>();
8870                                        }
8871                                        existingAuthorities.add(authority);
8872                                    } else {
8873                                        continue;
8874                                    }
8875                                }
8876                            }
8877                            result.add(perm.buildPersistedPublicApiObject());
8878                        }
8879                    }
8880                }
8881            } else {
8882                final int size = mGrantedUriPermissions.size();
8883                for (int i = 0; i < size; i++) {
8884                    final ArrayMap<GrantUri, UriPermission> perms =
8885                            mGrantedUriPermissions.valueAt(i);
8886                    for (UriPermission perm : perms.values()) {
8887                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8888                            result.add(perm.buildPersistedPublicApiObject());
8889                        }
8890                    }
8891                }
8892            }
8893        }
8894        return new ParceledListSlice<android.content.UriPermission>(result);
8895    }
8896
8897    @Override
8898    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8899            String packageName, int userId) {
8900        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8901                "getGrantedUriPermissions");
8902
8903        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8904        synchronized (this) {
8905            final int size = mGrantedUriPermissions.size();
8906            for (int i = 0; i < size; i++) {
8907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8908                for (UriPermission perm : perms.values()) {
8909                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8910                            && perm.persistedModeFlags != 0) {
8911                        result.add(perm.buildPersistedPublicApiObject());
8912                    }
8913                }
8914            }
8915        }
8916        return new ParceledListSlice<android.content.UriPermission>(result);
8917    }
8918
8919    @Override
8920    public void clearGrantedUriPermissions(String packageName, int userId) {
8921        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8922                "clearGrantedUriPermissions");
8923        removeUriPermissionsForPackageLocked(packageName, userId, true);
8924    }
8925
8926    @Override
8927    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8928        synchronized (this) {
8929            ProcessRecord app =
8930                who != null ? getRecordForAppLocked(who) : null;
8931            if (app == null) return;
8932
8933            Message msg = Message.obtain();
8934            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8935            msg.obj = app;
8936            msg.arg1 = waiting ? 1 : 0;
8937            mUiHandler.sendMessage(msg);
8938        }
8939    }
8940
8941    @Override
8942    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8943        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8944        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8945        outInfo.availMem = Process.getFreeMemory();
8946        outInfo.totalMem = Process.getTotalMemory();
8947        outInfo.threshold = homeAppMem;
8948        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8949        outInfo.hiddenAppThreshold = cachedAppMem;
8950        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8951                ProcessList.SERVICE_ADJ);
8952        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8953                ProcessList.VISIBLE_APP_ADJ);
8954        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8955                ProcessList.FOREGROUND_APP_ADJ);
8956    }
8957
8958    // =========================================================
8959    // TASK MANAGEMENT
8960    // =========================================================
8961
8962    @Override
8963    public List<IAppTask> getAppTasks(String callingPackage) {
8964        int callingUid = Binder.getCallingUid();
8965        long ident = Binder.clearCallingIdentity();
8966
8967        synchronized(this) {
8968            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8969            try {
8970                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8971
8972                final int N = mRecentTasks.size();
8973                for (int i = 0; i < N; i++) {
8974                    TaskRecord tr = mRecentTasks.get(i);
8975                    // Skip tasks that do not match the caller.  We don't need to verify
8976                    // callingPackage, because we are also limiting to callingUid and know
8977                    // that will limit to the correct security sandbox.
8978                    if (tr.effectiveUid != callingUid) {
8979                        continue;
8980                    }
8981                    Intent intent = tr.getBaseIntent();
8982                    if (intent == null ||
8983                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8984                        continue;
8985                    }
8986                    ActivityManager.RecentTaskInfo taskInfo =
8987                            createRecentTaskInfoFromTaskRecord(tr);
8988                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8989                    list.add(taskImpl);
8990                }
8991            } finally {
8992                Binder.restoreCallingIdentity(ident);
8993            }
8994            return list;
8995        }
8996    }
8997
8998    @Override
8999    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9000        final int callingUid = Binder.getCallingUid();
9001        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9002
9003        synchronized(this) {
9004            if (DEBUG_ALL) Slog.v(
9005                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9006
9007            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9008                    callingUid);
9009
9010            // TODO: Improve with MRU list from all ActivityStacks.
9011            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9012        }
9013
9014        return list;
9015    }
9016
9017    /**
9018     * Creates a new RecentTaskInfo from a TaskRecord.
9019     */
9020    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9021        // Update the task description to reflect any changes in the task stack
9022        tr.updateTaskDescription();
9023
9024        // Compose the recent task info
9025        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9026        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9027        rti.persistentId = tr.taskId;
9028        rti.baseIntent = new Intent(tr.getBaseIntent());
9029        rti.origActivity = tr.origActivity;
9030        rti.realActivity = tr.realActivity;
9031        rti.description = tr.lastDescription;
9032        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9033        rti.userId = tr.userId;
9034        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9035        rti.firstActiveTime = tr.firstActiveTime;
9036        rti.lastActiveTime = tr.lastActiveTime;
9037        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9038        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9039        rti.numActivities = 0;
9040        if (tr.mBounds != null) {
9041            rti.bounds = new Rect(tr.mBounds);
9042        }
9043        rti.isDockable = tr.canGoInDockedStack();
9044        rti.resizeMode = tr.mResizeMode;
9045
9046        ActivityRecord base = null;
9047        ActivityRecord top = null;
9048        ActivityRecord tmp;
9049
9050        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9051            tmp = tr.mActivities.get(i);
9052            if (tmp.finishing) {
9053                continue;
9054            }
9055            base = tmp;
9056            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9057                top = base;
9058            }
9059            rti.numActivities++;
9060        }
9061
9062        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9063        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9064
9065        return rti;
9066    }
9067
9068    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9069        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9070                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9071        if (!allowed) {
9072            if (checkPermission(android.Manifest.permission.GET_TASKS,
9073                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9074                // Temporary compatibility: some existing apps on the system image may
9075                // still be requesting the old permission and not switched to the new
9076                // one; if so, we'll still allow them full access.  This means we need
9077                // to see if they are holding the old permission and are a system app.
9078                try {
9079                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9080                        allowed = true;
9081                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9082                                + " is using old GET_TASKS but privileged; allowing");
9083                    }
9084                } catch (RemoteException e) {
9085                }
9086            }
9087        }
9088        if (!allowed) {
9089            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9090                    + " does not hold REAL_GET_TASKS; limiting output");
9091        }
9092        return allowed;
9093    }
9094
9095    @Override
9096    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9097        final int callingUid = Binder.getCallingUid();
9098        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9099                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9100
9101        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9102        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9103        synchronized (this) {
9104            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9105                    callingUid);
9106            final boolean detailed = checkCallingPermission(
9107                    android.Manifest.permission.GET_DETAILED_TASKS)
9108                    == PackageManager.PERMISSION_GRANTED;
9109
9110            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9111                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9112                return Collections.emptyList();
9113            }
9114            mRecentTasks.loadUserRecentsLocked(userId);
9115
9116            final int recentsCount = mRecentTasks.size();
9117            ArrayList<ActivityManager.RecentTaskInfo> res =
9118                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9119
9120            final Set<Integer> includedUsers;
9121            if (includeProfiles) {
9122                includedUsers = mUserController.getProfileIds(userId);
9123            } else {
9124                includedUsers = new HashSet<>();
9125            }
9126            includedUsers.add(Integer.valueOf(userId));
9127
9128            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9129                TaskRecord tr = mRecentTasks.get(i);
9130                // Only add calling user or related users recent tasks
9131                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9132                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9133                    continue;
9134                }
9135
9136                if (tr.realActivitySuspended) {
9137                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9138                    continue;
9139                }
9140
9141                // Return the entry if desired by the caller.  We always return
9142                // the first entry, because callers always expect this to be the
9143                // foreground app.  We may filter others if the caller has
9144                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9145                // we should exclude the entry.
9146
9147                if (i == 0
9148                        || withExcluded
9149                        || (tr.intent == null)
9150                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9151                                == 0)) {
9152                    if (!allowed) {
9153                        // If the caller doesn't have the GET_TASKS permission, then only
9154                        // allow them to see a small subset of tasks -- their own and home.
9155                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9156                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9157                            continue;
9158                        }
9159                    }
9160                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9161                        if (tr.stack != null && tr.stack.isHomeStack()) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9163                                    "Skipping, home stack task: " + tr);
9164                            continue;
9165                        }
9166                    }
9167                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9168                        final ActivityStack stack = tr.stack;
9169                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9170                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9171                                    "Skipping, top task in docked stack: " + tr);
9172                            continue;
9173                        }
9174                    }
9175                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9176                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9177                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9178                                    "Skipping, pinned stack task: " + tr);
9179                            continue;
9180                        }
9181                    }
9182                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9183                        // Don't include auto remove tasks that are finished or finishing.
9184                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9185                                "Skipping, auto-remove without activity: " + tr);
9186                        continue;
9187                    }
9188                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9189                            && !tr.isAvailable) {
9190                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9191                                "Skipping, unavail real act: " + tr);
9192                        continue;
9193                    }
9194
9195                    if (!tr.mUserSetupComplete) {
9196                        // Don't include task launched while user is not done setting-up.
9197                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9198                                "Skipping, user setup not complete: " + tr);
9199                        continue;
9200                    }
9201
9202                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9203                    if (!detailed) {
9204                        rti.baseIntent.replaceExtras((Bundle)null);
9205                    }
9206
9207                    res.add(rti);
9208                    maxNum--;
9209                }
9210            }
9211            return res;
9212        }
9213    }
9214
9215    @Override
9216    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9217        synchronized (this) {
9218            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9219                    "getTaskThumbnail()");
9220            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9221                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9222            if (tr != null) {
9223                return tr.getTaskThumbnailLocked();
9224            }
9225        }
9226        return null;
9227    }
9228
9229    @Override
9230    public int addAppTask(IBinder activityToken, Intent intent,
9231            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9232        final int callingUid = Binder.getCallingUid();
9233        final long callingIdent = Binder.clearCallingIdentity();
9234
9235        try {
9236            synchronized (this) {
9237                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9238                if (r == null) {
9239                    throw new IllegalArgumentException("Activity does not exist; token="
9240                            + activityToken);
9241                }
9242                ComponentName comp = intent.getComponent();
9243                if (comp == null) {
9244                    throw new IllegalArgumentException("Intent " + intent
9245                            + " must specify explicit component");
9246                }
9247                if (thumbnail.getWidth() != mThumbnailWidth
9248                        || thumbnail.getHeight() != mThumbnailHeight) {
9249                    throw new IllegalArgumentException("Bad thumbnail size: got "
9250                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9251                            + mThumbnailWidth + "x" + mThumbnailHeight);
9252                }
9253                if (intent.getSelector() != null) {
9254                    intent.setSelector(null);
9255                }
9256                if (intent.getSourceBounds() != null) {
9257                    intent.setSourceBounds(null);
9258                }
9259                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9260                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9261                        // The caller has added this as an auto-remove task...  that makes no
9262                        // sense, so turn off auto-remove.
9263                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9264                    }
9265                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9266                    // Must be a new task.
9267                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9268                }
9269                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9270                    mLastAddedTaskActivity = null;
9271                }
9272                ActivityInfo ainfo = mLastAddedTaskActivity;
9273                if (ainfo == null) {
9274                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9275                            comp, 0, UserHandle.getUserId(callingUid));
9276                    if (ainfo.applicationInfo.uid != callingUid) {
9277                        throw new SecurityException(
9278                                "Can't add task for another application: target uid="
9279                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9280                    }
9281                }
9282
9283                // Use the full screen as the context for the task thumbnail
9284                final Point displaySize = new Point();
9285                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9286                r.task.stack.getDisplaySize(displaySize);
9287                thumbnailInfo.taskWidth = displaySize.x;
9288                thumbnailInfo.taskHeight = displaySize.y;
9289                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9290
9291                TaskRecord task = new TaskRecord(this,
9292                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9293                        ainfo, intent, description, thumbnailInfo);
9294
9295                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9296                if (trimIdx >= 0) {
9297                    // If this would have caused a trim, then we'll abort because that
9298                    // means it would be added at the end of the list but then just removed.
9299                    return INVALID_TASK_ID;
9300                }
9301
9302                final int N = mRecentTasks.size();
9303                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9304                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9305                    tr.removedFromRecents();
9306                }
9307
9308                task.inRecents = true;
9309                mRecentTasks.add(task);
9310                r.task.stack.addTask(task, false, "addAppTask");
9311
9312                task.setLastThumbnailLocked(thumbnail);
9313                task.freeLastThumbnail();
9314
9315                return task.taskId;
9316            }
9317        } finally {
9318            Binder.restoreCallingIdentity(callingIdent);
9319        }
9320    }
9321
9322    @Override
9323    public Point getAppTaskThumbnailSize() {
9324        synchronized (this) {
9325            return new Point(mThumbnailWidth,  mThumbnailHeight);
9326        }
9327    }
9328
9329    @Override
9330    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9331        synchronized (this) {
9332            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9333            if (r != null) {
9334                r.setTaskDescription(td);
9335                r.task.updateTaskDescription();
9336            }
9337        }
9338    }
9339
9340    @Override
9341    public void setTaskResizeable(int taskId, int resizeableMode) {
9342        synchronized (this) {
9343            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9344                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9345            if (task == null) {
9346                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9347                return;
9348            }
9349            if (task.mResizeMode != resizeableMode) {
9350                task.mResizeMode = resizeableMode;
9351                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9352                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9353                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9354            }
9355        }
9356    }
9357
9358    @Override
9359    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9360        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9361        long ident = Binder.clearCallingIdentity();
9362        try {
9363            synchronized (this) {
9364                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9365                if (task == null) {
9366                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9367                    return;
9368                }
9369                int stackId = task.stack.mStackId;
9370                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9371                // in crop windows resize mode or if the task size is affected by the docked stack
9372                // changing size. No need to update configuration.
9373                if (bounds != null && task.inCropWindowsResizeMode()
9374                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9375                    mWindowManager.scrollTask(task.taskId, bounds);
9376                    return;
9377                }
9378
9379                // Place the task in the right stack if it isn't there already based on
9380                // the requested bounds.
9381                // The stack transition logic is:
9382                // - a null bounds on a freeform task moves that task to fullscreen
9383                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9384                //   that task to freeform
9385                // - otherwise the task is not moved
9386                if (!StackId.isTaskResizeAllowed(stackId)) {
9387                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9388                }
9389                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9390                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9391                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9392                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9393                }
9394                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9395                if (stackId != task.stack.mStackId) {
9396                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9397                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9398                    preserveWindow = false;
9399                }
9400
9401                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9402                        false /* deferResume */);
9403            }
9404        } finally {
9405            Binder.restoreCallingIdentity(ident);
9406        }
9407    }
9408
9409    @Override
9410    public Rect getTaskBounds(int taskId) {
9411        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9412        long ident = Binder.clearCallingIdentity();
9413        Rect rect = new Rect();
9414        try {
9415            synchronized (this) {
9416                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9417                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9418                if (task == null) {
9419                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9420                    return rect;
9421                }
9422                if (task.stack != null) {
9423                    // Return the bounds from window manager since it will be adjusted for various
9424                    // things like the presense of a docked stack for tasks that aren't resizeable.
9425                    mWindowManager.getTaskBounds(task.taskId, rect);
9426                } else {
9427                    // Task isn't in window manager yet since it isn't associated with a stack.
9428                    // Return the persist value from activity manager
9429                    if (task.mBounds != null) {
9430                        rect.set(task.mBounds);
9431                    } else if (task.mLastNonFullscreenBounds != null) {
9432                        rect.set(task.mLastNonFullscreenBounds);
9433                    }
9434                }
9435            }
9436        } finally {
9437            Binder.restoreCallingIdentity(ident);
9438        }
9439        return rect;
9440    }
9441
9442    @Override
9443    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9444        if (userId != UserHandle.getCallingUserId()) {
9445            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9446                    "getTaskDescriptionIcon");
9447        }
9448        final File passedIconFile = new File(filePath);
9449        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9450                passedIconFile.getName());
9451        if (!legitIconFile.getPath().equals(filePath)
9452                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9453            throw new IllegalArgumentException("Bad file path: " + filePath
9454                    + " passed for userId " + userId);
9455        }
9456        return mRecentTasks.getTaskDescriptionIcon(filePath);
9457    }
9458
9459    @Override
9460    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9461            throws RemoteException {
9462        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9463                opts.getCustomInPlaceResId() == 0) {
9464            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9465                    "with valid animation");
9466        }
9467        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9468        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9469                opts.getCustomInPlaceResId());
9470        mWindowManager.executeAppTransition();
9471    }
9472
9473    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9474            boolean removeFromRecents) {
9475        if (removeFromRecents) {
9476            mRecentTasks.remove(tr);
9477            tr.removedFromRecents();
9478        }
9479        ComponentName component = tr.getBaseIntent().getComponent();
9480        if (component == null) {
9481            Slog.w(TAG, "No component for base intent of task: " + tr);
9482            return;
9483        }
9484
9485        // Find any running services associated with this app and stop if needed.
9486        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9487
9488        if (!killProcess) {
9489            return;
9490        }
9491
9492        // Determine if the process(es) for this task should be killed.
9493        final String pkg = component.getPackageName();
9494        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9495        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9496        for (int i = 0; i < pmap.size(); i++) {
9497
9498            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9499            for (int j = 0; j < uids.size(); j++) {
9500                ProcessRecord proc = uids.valueAt(j);
9501                if (proc.userId != tr.userId) {
9502                    // Don't kill process for a different user.
9503                    continue;
9504                }
9505                if (proc == mHomeProcess) {
9506                    // Don't kill the home process along with tasks from the same package.
9507                    continue;
9508                }
9509                if (!proc.pkgList.containsKey(pkg)) {
9510                    // Don't kill process that is not associated with this task.
9511                    continue;
9512                }
9513
9514                for (int k = 0; k < proc.activities.size(); k++) {
9515                    TaskRecord otherTask = proc.activities.get(k).task;
9516                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9517                        // Don't kill process(es) that has an activity in a different task that is
9518                        // also in recents.
9519                        return;
9520                    }
9521                }
9522
9523                if (proc.foregroundServices) {
9524                    // Don't kill process(es) with foreground service.
9525                    return;
9526                }
9527
9528                // Add process to kill list.
9529                procsToKill.add(proc);
9530            }
9531        }
9532
9533        // Kill the running processes.
9534        for (int i = 0; i < procsToKill.size(); i++) {
9535            ProcessRecord pr = procsToKill.get(i);
9536            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9537                    && pr.curReceiver == null) {
9538                pr.kill("remove task", true);
9539            } else {
9540                // We delay killing processes that are not in the background or running a receiver.
9541                pr.waitingToKill = "remove task";
9542            }
9543        }
9544    }
9545
9546    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9547        // Remove all tasks with activities in the specified package from the list of recent tasks
9548        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9549            TaskRecord tr = mRecentTasks.get(i);
9550            if (tr.userId != userId) continue;
9551
9552            ComponentName cn = tr.intent.getComponent();
9553            if (cn != null && cn.getPackageName().equals(packageName)) {
9554                // If the package name matches, remove the task.
9555                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9556            }
9557        }
9558    }
9559
9560    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9561            int userId) {
9562
9563        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9564            TaskRecord tr = mRecentTasks.get(i);
9565            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9566                continue;
9567            }
9568
9569            ComponentName cn = tr.intent.getComponent();
9570            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9571                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9572            if (sameComponent) {
9573                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9574            }
9575        }
9576    }
9577
9578    /**
9579     * Removes the task with the specified task id.
9580     *
9581     * @param taskId Identifier of the task to be removed.
9582     * @param killProcess Kill any process associated with the task if possible.
9583     * @param removeFromRecents Whether to also remove the task from recents.
9584     * @return Returns true if the given task was found and removed.
9585     */
9586    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9587            boolean removeFromRecents) {
9588        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9589                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9590        if (tr != null) {
9591            tr.removeTaskActivitiesLocked();
9592            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9593            if (tr.isPersistable) {
9594                notifyTaskPersisterLocked(null, true);
9595            }
9596            return true;
9597        }
9598        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9599        return false;
9600    }
9601
9602    @Override
9603    public void removeStack(int stackId) {
9604        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9605        if (stackId == HOME_STACK_ID) {
9606            throw new IllegalArgumentException("Removing home stack is not allowed.");
9607        }
9608
9609        synchronized (this) {
9610            final long ident = Binder.clearCallingIdentity();
9611            try {
9612                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9613                if (stack == null) {
9614                    return;
9615                }
9616                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9617                for (int i = tasks.size() - 1; i >= 0; i--) {
9618                    removeTaskByIdLocked(
9619                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9620                }
9621            } finally {
9622                Binder.restoreCallingIdentity(ident);
9623            }
9624        }
9625    }
9626
9627    @Override
9628    public boolean removeTask(int taskId) {
9629        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9630        synchronized (this) {
9631            final long ident = Binder.clearCallingIdentity();
9632            try {
9633                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9634            } finally {
9635                Binder.restoreCallingIdentity(ident);
9636            }
9637        }
9638    }
9639
9640    /**
9641     * TODO: Add mController hook
9642     */
9643    @Override
9644    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9645        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9646
9647        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9648        synchronized(this) {
9649            moveTaskToFrontLocked(taskId, flags, bOptions);
9650        }
9651    }
9652
9653    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9654        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9655
9656        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9657                Binder.getCallingUid(), -1, -1, "Task to front")) {
9658            ActivityOptions.abort(options);
9659            return;
9660        }
9661        final long origId = Binder.clearCallingIdentity();
9662        try {
9663            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9664            if (task == null) {
9665                Slog.d(TAG, "Could not find task for id: "+ taskId);
9666                return;
9667            }
9668            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9669                mStackSupervisor.showLockTaskToast();
9670                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9671                return;
9672            }
9673            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9674            if (prev != null && prev.isRecentsActivity()) {
9675                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9676            }
9677            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9678                    false /* forceNonResizable */);
9679        } finally {
9680            Binder.restoreCallingIdentity(origId);
9681        }
9682        ActivityOptions.abort(options);
9683    }
9684
9685    /**
9686     * Moves an activity, and all of the other activities within the same task, to the bottom
9687     * of the history stack.  The activity's order within the task is unchanged.
9688     *
9689     * @param token A reference to the activity we wish to move
9690     * @param nonRoot If false then this only works if the activity is the root
9691     *                of a task; if true it will work for any activity in a task.
9692     * @return Returns true if the move completed, false if not.
9693     */
9694    @Override
9695    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9696        enforceNotIsolatedCaller("moveActivityTaskToBack");
9697        synchronized(this) {
9698            final long origId = Binder.clearCallingIdentity();
9699            try {
9700                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9701                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9702                if (task != null) {
9703                    if (mStackSupervisor.isLockedTask(task)) {
9704                        mStackSupervisor.showLockTaskToast();
9705                        return false;
9706                    }
9707                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9708                }
9709            } finally {
9710                Binder.restoreCallingIdentity(origId);
9711            }
9712        }
9713        return false;
9714    }
9715
9716    @Override
9717    public void moveTaskBackwards(int task) {
9718        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9719                "moveTaskBackwards()");
9720
9721        synchronized(this) {
9722            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9723                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9724                return;
9725            }
9726            final long origId = Binder.clearCallingIdentity();
9727            moveTaskBackwardsLocked(task);
9728            Binder.restoreCallingIdentity(origId);
9729        }
9730    }
9731
9732    private final void moveTaskBackwardsLocked(int task) {
9733        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9734    }
9735
9736    @Override
9737    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9738            IActivityContainerCallback callback) throws RemoteException {
9739        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9740        synchronized (this) {
9741            if (parentActivityToken == null) {
9742                throw new IllegalArgumentException("parent token must not be null");
9743            }
9744            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9745            if (r == null) {
9746                return null;
9747            }
9748            if (callback == null) {
9749                throw new IllegalArgumentException("callback must not be null");
9750            }
9751            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9752        }
9753    }
9754
9755    @Override
9756    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9757        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9758        synchronized (this) {
9759            mStackSupervisor.deleteActivityContainer(container);
9760        }
9761    }
9762
9763    @Override
9764    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9765        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9766        synchronized (this) {
9767            final int stackId = mStackSupervisor.getNextStackId();
9768            final ActivityStack stack =
9769                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9770            if (stack == null) {
9771                return null;
9772            }
9773            return stack.mActivityContainer;
9774        }
9775    }
9776
9777    @Override
9778    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9779        synchronized (this) {
9780            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9781            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9782                return stack.mActivityContainer.getDisplayId();
9783            }
9784            return Display.DEFAULT_DISPLAY;
9785        }
9786    }
9787
9788    @Override
9789    public int getActivityStackId(IBinder token) throws RemoteException {
9790        synchronized (this) {
9791            ActivityStack stack = ActivityRecord.getStackLocked(token);
9792            if (stack == null) {
9793                return INVALID_STACK_ID;
9794            }
9795            return stack.mStackId;
9796        }
9797    }
9798
9799    @Override
9800    public void exitFreeformMode(IBinder token) throws RemoteException {
9801        synchronized (this) {
9802            long ident = Binder.clearCallingIdentity();
9803            try {
9804                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9805                if (r == null) {
9806                    throw new IllegalArgumentException(
9807                            "exitFreeformMode: No activity record matching token=" + token);
9808                }
9809                final ActivityStack stack = r.getStackLocked(token);
9810                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9811                    throw new IllegalStateException(
9812                            "exitFreeformMode: You can only go fullscreen from freeform.");
9813                }
9814                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9815                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9816                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9817            } finally {
9818                Binder.restoreCallingIdentity(ident);
9819            }
9820        }
9821    }
9822
9823    @Override
9824    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9825        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9826        if (stackId == HOME_STACK_ID) {
9827            throw new IllegalArgumentException(
9828                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9829        }
9830        synchronized (this) {
9831            long ident = Binder.clearCallingIdentity();
9832            try {
9833                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9834                        + " to stackId=" + stackId + " toTop=" + toTop);
9835                if (stackId == DOCKED_STACK_ID) {
9836                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9837                            null /* initialBounds */);
9838                }
9839                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9840                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9841                if (result && stackId == DOCKED_STACK_ID) {
9842                    // If task moved to docked stack - show recents if needed.
9843                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9844                            "moveTaskToDockedStack");
9845                }
9846            } finally {
9847                Binder.restoreCallingIdentity(ident);
9848            }
9849        }
9850    }
9851
9852    @Override
9853    public void swapDockedAndFullscreenStack() throws RemoteException {
9854        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9855        synchronized (this) {
9856            long ident = Binder.clearCallingIdentity();
9857            try {
9858                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9859                        FULLSCREEN_WORKSPACE_STACK_ID);
9860                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9861                        : null;
9862                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9863                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9864                        : null;
9865                if (topTask == null || tasks == null || tasks.size() == 0) {
9866                    Slog.w(TAG,
9867                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9868                    return;
9869                }
9870
9871                // TODO: App transition
9872                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9873
9874                // Defer the resume so resume/pausing while moving stacks is dangerous.
9875                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9876                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9877                        ANIMATE, true /* deferResume */);
9878                final int size = tasks.size();
9879                for (int i = 0; i < size; i++) {
9880                    final int id = tasks.get(i).taskId;
9881                    if (id == topTask.taskId) {
9882                        continue;
9883                    }
9884                    mStackSupervisor.moveTaskToStackLocked(id,
9885                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9886                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9887                }
9888
9889                // Because we deferred the resume, to avoid conflicts with stack switches while
9890                // resuming, we need to do it after all the tasks are moved.
9891                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9892                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9893
9894                mWindowManager.executeAppTransition();
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899    }
9900
9901    /**
9902     * Moves the input task to the docked stack.
9903     *
9904     * @param taskId Id of task to move.
9905     * @param createMode The mode the docked stack should be created in if it doesn't exist
9906     *                   already. See
9907     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9908     *                   and
9909     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9910     * @param toTop If the task and stack should be moved to the top.
9911     * @param animate Whether we should play an animation for the moving the task
9912     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9913     *                      docked stack. Pass {@code null} to use default bounds.
9914     */
9915    @Override
9916    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9917            Rect initialBounds, boolean moveHomeStackFront) {
9918        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9919        synchronized (this) {
9920            long ident = Binder.clearCallingIdentity();
9921            try {
9922                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9923                        + " to createMode=" + createMode + " toTop=" + toTop);
9924                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9925                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9926                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9927                        animate, DEFER_RESUME);
9928                if (moved) {
9929                    if (moveHomeStackFront) {
9930                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9931                    }
9932                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9933                }
9934                return moved;
9935            } finally {
9936                Binder.restoreCallingIdentity(ident);
9937            }
9938        }
9939    }
9940
9941    /**
9942     * Moves the top activity in the input stackId to the pinned stack.
9943     *
9944     * @param stackId Id of stack to move the top activity to pinned stack.
9945     * @param bounds Bounds to use for pinned stack.
9946     *
9947     * @return True if the top activity of the input stack was successfully moved to the pinned
9948     *          stack.
9949     */
9950    @Override
9951    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9952        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9953        synchronized (this) {
9954            if (!mSupportsPictureInPicture) {
9955                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9956                        + "Device doesn't support picture-in-pciture mode");
9957            }
9958
9959            long ident = Binder.clearCallingIdentity();
9960            try {
9961                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9962            } finally {
9963                Binder.restoreCallingIdentity(ident);
9964            }
9965        }
9966    }
9967
9968    @Override
9969    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9970            boolean preserveWindows, boolean animate, int animationDuration) {
9971        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9972        long ident = Binder.clearCallingIdentity();
9973        try {
9974            synchronized (this) {
9975                if (animate) {
9976                    if (stackId == PINNED_STACK_ID) {
9977                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9978                    } else {
9979                        throw new IllegalArgumentException("Stack: " + stackId
9980                                + " doesn't support animated resize.");
9981                    }
9982                } else {
9983                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9984                            null /* tempTaskInsetBounds */, preserveWindows,
9985                            allowResizeInDockedMode, !DEFER_RESUME);
9986                }
9987            }
9988        } finally {
9989            Binder.restoreCallingIdentity(ident);
9990        }
9991    }
9992
9993    @Override
9994    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9995            Rect tempDockedTaskInsetBounds,
9996            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9997        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9998                "resizeDockedStack()");
9999        long ident = Binder.clearCallingIdentity();
10000        try {
10001            synchronized (this) {
10002                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10003                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10004                        PRESERVE_WINDOWS);
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    @Override
10012    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10013        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10014                "resizePinnedStack()");
10015        final long ident = Binder.clearCallingIdentity();
10016        try {
10017            synchronized (this) {
10018                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    @Override
10026    public void positionTaskInStack(int taskId, int stackId, int position) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10028        if (stackId == HOME_STACK_ID) {
10029            throw new IllegalArgumentException(
10030                    "positionTaskInStack: Attempt to change the position of task "
10031                    + taskId + " in/to home stack");
10032        }
10033        synchronized (this) {
10034            long ident = Binder.clearCallingIdentity();
10035            try {
10036                if (DEBUG_STACK) Slog.d(TAG_STACK,
10037                        "positionTaskInStack: positioning task=" + taskId
10038                        + " in stackId=" + stackId + " at position=" + position);
10039                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10040            } finally {
10041                Binder.restoreCallingIdentity(ident);
10042            }
10043        }
10044    }
10045
10046    @Override
10047    public List<StackInfo> getAllStackInfos() {
10048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10049        long ident = Binder.clearCallingIdentity();
10050        try {
10051            synchronized (this) {
10052                return mStackSupervisor.getAllStackInfosLocked();
10053            }
10054        } finally {
10055            Binder.restoreCallingIdentity(ident);
10056        }
10057    }
10058
10059    @Override
10060    public StackInfo getStackInfo(int stackId) {
10061        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10062        long ident = Binder.clearCallingIdentity();
10063        try {
10064            synchronized (this) {
10065                return mStackSupervisor.getStackInfoLocked(stackId);
10066            }
10067        } finally {
10068            Binder.restoreCallingIdentity(ident);
10069        }
10070    }
10071
10072    @Override
10073    public boolean isInHomeStack(int taskId) {
10074        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10075        long ident = Binder.clearCallingIdentity();
10076        try {
10077            synchronized (this) {
10078                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10079                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10080                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10081            }
10082        } finally {
10083            Binder.restoreCallingIdentity(ident);
10084        }
10085    }
10086
10087    @Override
10088    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10089        synchronized(this) {
10090            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10091        }
10092    }
10093
10094    @Override
10095    public void updateDeviceOwner(String packageName) {
10096        final int callingUid = Binder.getCallingUid();
10097        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10098            throw new SecurityException("updateDeviceOwner called from non-system process");
10099        }
10100        synchronized (this) {
10101            mDeviceOwnerName = packageName;
10102        }
10103    }
10104
10105    @Override
10106    public void updateLockTaskPackages(int userId, String[] packages) {
10107        final int callingUid = Binder.getCallingUid();
10108        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10109            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10110                    "updateLockTaskPackages()");
10111        }
10112        synchronized (this) {
10113            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10114                    Arrays.toString(packages));
10115            mLockTaskPackages.put(userId, packages);
10116            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10117        }
10118    }
10119
10120
10121    void startLockTaskModeLocked(TaskRecord task) {
10122        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10123        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10124            return;
10125        }
10126
10127        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10128        // is initiated by system after the pinning request was shown and locked mode is initiated
10129        // by an authorized app directly
10130        final int callingUid = Binder.getCallingUid();
10131        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10132        long ident = Binder.clearCallingIdentity();
10133        try {
10134            if (!isSystemInitiated) {
10135                task.mLockTaskUid = callingUid;
10136                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10137                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10138                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10139                    StatusBarManagerInternal statusBarManager =
10140                            LocalServices.getService(StatusBarManagerInternal.class);
10141                    if (statusBarManager != null) {
10142                        statusBarManager.showScreenPinningRequest(task.taskId);
10143                    }
10144                    return;
10145                }
10146
10147                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10148                if (stack == null || task != stack.topTask()) {
10149                    throw new IllegalArgumentException("Invalid task, not in foreground");
10150                }
10151            }
10152            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10153                    "Locking fully");
10154            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10155                    ActivityManager.LOCK_TASK_MODE_PINNED :
10156                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10157                    "startLockTask", true);
10158        } finally {
10159            Binder.restoreCallingIdentity(ident);
10160        }
10161    }
10162
10163    @Override
10164    public void startLockTaskMode(int taskId) {
10165        synchronized (this) {
10166            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10167            if (task != null) {
10168                startLockTaskModeLocked(task);
10169            }
10170        }
10171    }
10172
10173    @Override
10174    public void startLockTaskMode(IBinder token) {
10175        synchronized (this) {
10176            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10177            if (r == null) {
10178                return;
10179            }
10180            final TaskRecord task = r.task;
10181            if (task != null) {
10182                startLockTaskModeLocked(task);
10183            }
10184        }
10185    }
10186
10187    @Override
10188    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10189        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10190        // This makes inner call to look as if it was initiated by system.
10191        long ident = Binder.clearCallingIdentity();
10192        try {
10193            synchronized (this) {
10194                startLockTaskMode(taskId);
10195            }
10196        } finally {
10197            Binder.restoreCallingIdentity(ident);
10198        }
10199    }
10200
10201    @Override
10202    public void stopLockTaskMode() {
10203        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10204        if (lockTask == null) {
10205            // Our work here is done.
10206            return;
10207        }
10208
10209        final int callingUid = Binder.getCallingUid();
10210        final int lockTaskUid = lockTask.mLockTaskUid;
10211        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10212        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10213            // Done.
10214            return;
10215        } else {
10216            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10217            // It is possible lockTaskMode was started by the system process because
10218            // android:lockTaskMode is set to a locking value in the application manifest
10219            // instead of the app calling startLockTaskMode. In this case
10220            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10221            // {@link TaskRecord.effectiveUid} instead. Also caller with
10222            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10223            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10224                    && callingUid != lockTaskUid
10225                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10226                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10227                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10228            }
10229        }
10230        long ident = Binder.clearCallingIdentity();
10231        try {
10232            Log.d(TAG, "stopLockTaskMode");
10233            // Stop lock task
10234            synchronized (this) {
10235                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10236                        "stopLockTask", true);
10237            }
10238            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10239            if (tm != null) {
10240                tm.showInCallScreen(false);
10241            }
10242        } finally {
10243            Binder.restoreCallingIdentity(ident);
10244        }
10245    }
10246
10247    /**
10248     * This API should be called by SystemUI only when user perform certain action to dismiss
10249     * lock task mode. We should only dismiss pinned lock task mode in this case.
10250     */
10251    @Override
10252    public void stopSystemLockTaskMode() throws RemoteException {
10253        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10254            stopLockTaskMode();
10255        } else {
10256            mStackSupervisor.showLockTaskToast();
10257        }
10258    }
10259
10260    @Override
10261    public boolean isInLockTaskMode() {
10262        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10263    }
10264
10265    @Override
10266    public int getLockTaskModeState() {
10267        synchronized (this) {
10268            return mStackSupervisor.getLockTaskModeState();
10269        }
10270    }
10271
10272    @Override
10273    public void showLockTaskEscapeMessage(IBinder token) {
10274        synchronized (this) {
10275            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10276            if (r == null) {
10277                return;
10278            }
10279            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10280        }
10281    }
10282
10283    // =========================================================
10284    // CONTENT PROVIDERS
10285    // =========================================================
10286
10287    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10288        List<ProviderInfo> providers = null;
10289        try {
10290            providers = AppGlobals.getPackageManager()
10291                    .queryContentProviders(app.processName, app.uid,
10292                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10293                                    | MATCH_DEBUG_TRIAGED_MISSING)
10294                    .getList();
10295        } catch (RemoteException ex) {
10296        }
10297        if (DEBUG_MU) Slog.v(TAG_MU,
10298                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10299        int userId = app.userId;
10300        if (providers != null) {
10301            int N = providers.size();
10302            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10303            for (int i=0; i<N; i++) {
10304                // TODO: keep logic in sync with installEncryptionUnawareProviders
10305                ProviderInfo cpi =
10306                    (ProviderInfo)providers.get(i);
10307                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10308                        cpi.name, cpi.flags);
10309                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10310                    // This is a singleton provider, but a user besides the
10311                    // default user is asking to initialize a process it runs
10312                    // in...  well, no, it doesn't actually run in this process,
10313                    // it runs in the process of the default user.  Get rid of it.
10314                    providers.remove(i);
10315                    N--;
10316                    i--;
10317                    continue;
10318                }
10319
10320                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10321                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10322                if (cpr == null) {
10323                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10324                    mProviderMap.putProviderByClass(comp, cpr);
10325                }
10326                if (DEBUG_MU) Slog.v(TAG_MU,
10327                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10328                app.pubProviders.put(cpi.name, cpr);
10329                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10330                    // Don't add this if it is a platform component that is marked
10331                    // to run in multiple processes, because this is actually
10332                    // part of the framework so doesn't make sense to track as a
10333                    // separate apk in the process.
10334                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10335                            mProcessStats);
10336                }
10337                notifyPackageUse(cpi.applicationInfo.packageName,
10338                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10339            }
10340        }
10341        return providers;
10342    }
10343
10344    /**
10345     * Check if {@link ProcessRecord} has a possible chance at accessing the
10346     * given {@link ProviderInfo}. Final permission checking is always done
10347     * in {@link ContentProvider}.
10348     */
10349    private final String checkContentProviderPermissionLocked(
10350            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10351        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10352        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10353        boolean checkedGrants = false;
10354        if (checkUser) {
10355            // Looking for cross-user grants before enforcing the typical cross-users permissions
10356            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10357            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10358                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10359                    return null;
10360                }
10361                checkedGrants = true;
10362            }
10363            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10364                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10365            if (userId != tmpTargetUserId) {
10366                // When we actually went to determine the final targer user ID, this ended
10367                // up different than our initial check for the authority.  This is because
10368                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10369                // SELF.  So we need to re-check the grants again.
10370                checkedGrants = false;
10371            }
10372        }
10373        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10374                cpi.applicationInfo.uid, cpi.exported)
10375                == PackageManager.PERMISSION_GRANTED) {
10376            return null;
10377        }
10378        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10379                cpi.applicationInfo.uid, cpi.exported)
10380                == PackageManager.PERMISSION_GRANTED) {
10381            return null;
10382        }
10383
10384        PathPermission[] pps = cpi.pathPermissions;
10385        if (pps != null) {
10386            int i = pps.length;
10387            while (i > 0) {
10388                i--;
10389                PathPermission pp = pps[i];
10390                String pprperm = pp.getReadPermission();
10391                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10392                        cpi.applicationInfo.uid, cpi.exported)
10393                        == PackageManager.PERMISSION_GRANTED) {
10394                    return null;
10395                }
10396                String ppwperm = pp.getWritePermission();
10397                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10398                        cpi.applicationInfo.uid, cpi.exported)
10399                        == PackageManager.PERMISSION_GRANTED) {
10400                    return null;
10401                }
10402            }
10403        }
10404        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10405            return null;
10406        }
10407
10408        String msg;
10409        if (!cpi.exported) {
10410            msg = "Permission Denial: opening provider " + cpi.name
10411                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10412                    + ", uid=" + callingUid + ") that is not exported from uid "
10413                    + cpi.applicationInfo.uid;
10414        } else {
10415            msg = "Permission Denial: opening provider " + cpi.name
10416                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10417                    + ", uid=" + callingUid + ") requires "
10418                    + cpi.readPermission + " or " + cpi.writePermission;
10419        }
10420        Slog.w(TAG, msg);
10421        return msg;
10422    }
10423
10424    /**
10425     * Returns if the ContentProvider has granted a uri to callingUid
10426     */
10427    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10428        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10429        if (perms != null) {
10430            for (int i=perms.size()-1; i>=0; i--) {
10431                GrantUri grantUri = perms.keyAt(i);
10432                if (grantUri.sourceUserId == userId || !checkUser) {
10433                    if (matchesProvider(grantUri.uri, cpi)) {
10434                        return true;
10435                    }
10436                }
10437            }
10438        }
10439        return false;
10440    }
10441
10442    /**
10443     * Returns true if the uri authority is one of the authorities specified in the provider.
10444     */
10445    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10446        String uriAuth = uri.getAuthority();
10447        String cpiAuth = cpi.authority;
10448        if (cpiAuth.indexOf(';') == -1) {
10449            return cpiAuth.equals(uriAuth);
10450        }
10451        String[] cpiAuths = cpiAuth.split(";");
10452        int length = cpiAuths.length;
10453        for (int i = 0; i < length; i++) {
10454            if (cpiAuths[i].equals(uriAuth)) return true;
10455        }
10456        return false;
10457    }
10458
10459    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10460            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10461        if (r != null) {
10462            for (int i=0; i<r.conProviders.size(); i++) {
10463                ContentProviderConnection conn = r.conProviders.get(i);
10464                if (conn.provider == cpr) {
10465                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10466                            "Adding provider requested by "
10467                            + r.processName + " from process "
10468                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10469                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10470                    if (stable) {
10471                        conn.stableCount++;
10472                        conn.numStableIncs++;
10473                    } else {
10474                        conn.unstableCount++;
10475                        conn.numUnstableIncs++;
10476                    }
10477                    return conn;
10478                }
10479            }
10480            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10481            if (stable) {
10482                conn.stableCount = 1;
10483                conn.numStableIncs = 1;
10484            } else {
10485                conn.unstableCount = 1;
10486                conn.numUnstableIncs = 1;
10487            }
10488            cpr.connections.add(conn);
10489            r.conProviders.add(conn);
10490            startAssociationLocked(r.uid, r.processName, r.curProcState,
10491                    cpr.uid, cpr.name, cpr.info.processName);
10492            return conn;
10493        }
10494        cpr.addExternalProcessHandleLocked(externalProcessToken);
10495        return null;
10496    }
10497
10498    boolean decProviderCountLocked(ContentProviderConnection conn,
10499            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10500        if (conn != null) {
10501            cpr = conn.provider;
10502            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10503                    "Removing provider requested by "
10504                    + conn.client.processName + " from process "
10505                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10506                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10507            if (stable) {
10508                conn.stableCount--;
10509            } else {
10510                conn.unstableCount--;
10511            }
10512            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10513                cpr.connections.remove(conn);
10514                conn.client.conProviders.remove(conn);
10515                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10516                    // The client is more important than last activity -- note the time this
10517                    // is happening, so we keep the old provider process around a bit as last
10518                    // activity to avoid thrashing it.
10519                    if (cpr.proc != null) {
10520                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10521                    }
10522                }
10523                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10524                return true;
10525            }
10526            return false;
10527        }
10528        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10529        return false;
10530    }
10531
10532    private void checkTime(long startTime, String where) {
10533        long now = SystemClock.uptimeMillis();
10534        if ((now-startTime) > 50) {
10535            // If we are taking more than 50ms, log about it.
10536            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10537        }
10538    }
10539
10540    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10541            String name, IBinder token, boolean stable, int userId) {
10542        ContentProviderRecord cpr;
10543        ContentProviderConnection conn = null;
10544        ProviderInfo cpi = null;
10545
10546        synchronized(this) {
10547            long startTime = SystemClock.uptimeMillis();
10548
10549            ProcessRecord r = null;
10550            if (caller != null) {
10551                r = getRecordForAppLocked(caller);
10552                if (r == null) {
10553                    throw new SecurityException(
10554                            "Unable to find app for caller " + caller
10555                          + " (pid=" + Binder.getCallingPid()
10556                          + ") when getting content provider " + name);
10557                }
10558            }
10559
10560            boolean checkCrossUser = true;
10561
10562            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10563
10564            // First check if this content provider has been published...
10565            cpr = mProviderMap.getProviderByName(name, userId);
10566            // If that didn't work, check if it exists for user 0 and then
10567            // verify that it's a singleton provider before using it.
10568            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10569                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10570                if (cpr != null) {
10571                    cpi = cpr.info;
10572                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10573                            cpi.name, cpi.flags)
10574                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10575                        userId = UserHandle.USER_SYSTEM;
10576                        checkCrossUser = false;
10577                    } else {
10578                        cpr = null;
10579                        cpi = null;
10580                    }
10581                }
10582            }
10583
10584            boolean providerRunning = cpr != null;
10585            if (providerRunning) {
10586                cpi = cpr.info;
10587                String msg;
10588                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10589                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10590                        != null) {
10591                    throw new SecurityException(msg);
10592                }
10593                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10594
10595                if (r != null && cpr.canRunHere(r)) {
10596                    // This provider has been published or is in the process
10597                    // of being published...  but it is also allowed to run
10598                    // in the caller's process, so don't make a connection
10599                    // and just let the caller instantiate its own instance.
10600                    ContentProviderHolder holder = cpr.newHolder(null);
10601                    // don't give caller the provider object, it needs
10602                    // to make its own.
10603                    holder.provider = null;
10604                    return holder;
10605                }
10606
10607                final long origId = Binder.clearCallingIdentity();
10608
10609                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10610
10611                // In this case the provider instance already exists, so we can
10612                // return it right away.
10613                conn = incProviderCountLocked(r, cpr, token, stable);
10614                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10615                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10616                        // If this is a perceptible app accessing the provider,
10617                        // make sure to count it as being accessed and thus
10618                        // back up on the LRU list.  This is good because
10619                        // content providers are often expensive to start.
10620                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10621                        updateLruProcessLocked(cpr.proc, false, null);
10622                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10623                    }
10624                }
10625
10626                if (cpr.proc != null) {
10627                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10628                    boolean success = updateOomAdjLocked(cpr.proc);
10629                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10630                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10631                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10632                    // NOTE: there is still a race here where a signal could be
10633                    // pending on the process even though we managed to update its
10634                    // adj level.  Not sure what to do about this, but at least
10635                    // the race is now smaller.
10636                    if (!success) {
10637                        // Uh oh...  it looks like the provider's process
10638                        // has been killed on us.  We need to wait for a new
10639                        // process to be started, and make sure its death
10640                        // doesn't kill our process.
10641                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10642                                + " is crashing; detaching " + r);
10643                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10644                        checkTime(startTime, "getContentProviderImpl: before appDied");
10645                        appDiedLocked(cpr.proc);
10646                        checkTime(startTime, "getContentProviderImpl: after appDied");
10647                        if (!lastRef) {
10648                            // This wasn't the last ref our process had on
10649                            // the provider...  we have now been killed, bail.
10650                            return null;
10651                        }
10652                        providerRunning = false;
10653                        conn = null;
10654                    }
10655                }
10656
10657                Binder.restoreCallingIdentity(origId);
10658            }
10659
10660            if (!providerRunning) {
10661                try {
10662                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10663                    cpi = AppGlobals.getPackageManager().
10664                        resolveContentProvider(name,
10665                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10666                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10667                } catch (RemoteException ex) {
10668                }
10669                if (cpi == null) {
10670                    return null;
10671                }
10672                // If the provider is a singleton AND
10673                // (it's a call within the same user || the provider is a
10674                // privileged app)
10675                // Then allow connecting to the singleton provider
10676                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10677                        cpi.name, cpi.flags)
10678                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10679                if (singleton) {
10680                    userId = UserHandle.USER_SYSTEM;
10681                }
10682                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10683                checkTime(startTime, "getContentProviderImpl: got app info for user");
10684
10685                String msg;
10686                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10687                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10688                        != null) {
10689                    throw new SecurityException(msg);
10690                }
10691                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10692
10693                if (!mProcessesReady
10694                        && !cpi.processName.equals("system")) {
10695                    // If this content provider does not run in the system
10696                    // process, and the system is not yet ready to run other
10697                    // processes, then fail fast instead of hanging.
10698                    throw new IllegalArgumentException(
10699                            "Attempt to launch content provider before system ready");
10700                }
10701
10702                // Make sure that the user who owns this provider is running.  If not,
10703                // we don't want to allow it to run.
10704                if (!mUserController.isUserRunningLocked(userId, 0)) {
10705                    Slog.w(TAG, "Unable to launch app "
10706                            + cpi.applicationInfo.packageName + "/"
10707                            + cpi.applicationInfo.uid + " for provider "
10708                            + name + ": user " + userId + " is stopped");
10709                    return null;
10710                }
10711
10712                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10713                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10714                cpr = mProviderMap.getProviderByClass(comp, userId);
10715                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10716                final boolean firstClass = cpr == null;
10717                if (firstClass) {
10718                    final long ident = Binder.clearCallingIdentity();
10719
10720                    // If permissions need a review before any of the app components can run,
10721                    // we return no provider and launch a review activity if the calling app
10722                    // is in the foreground.
10723                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10724                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10725                            return null;
10726                        }
10727                    }
10728
10729                    try {
10730                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10731                        ApplicationInfo ai =
10732                            AppGlobals.getPackageManager().
10733                                getApplicationInfo(
10734                                        cpi.applicationInfo.packageName,
10735                                        STOCK_PM_FLAGS, userId);
10736                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10737                        if (ai == null) {
10738                            Slog.w(TAG, "No package info for content provider "
10739                                    + cpi.name);
10740                            return null;
10741                        }
10742                        ai = getAppInfoForUser(ai, userId);
10743                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10744                    } catch (RemoteException ex) {
10745                        // pm is in same process, this will never happen.
10746                    } finally {
10747                        Binder.restoreCallingIdentity(ident);
10748                    }
10749                }
10750
10751                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10752
10753                if (r != null && cpr.canRunHere(r)) {
10754                    // If this is a multiprocess provider, then just return its
10755                    // info and allow the caller to instantiate it.  Only do
10756                    // this if the provider is the same user as the caller's
10757                    // process, or can run as root (so can be in any process).
10758                    return cpr.newHolder(null);
10759                }
10760
10761                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10762                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10763                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10764
10765                // This is single process, and our app is now connecting to it.
10766                // See if we are already in the process of launching this
10767                // provider.
10768                final int N = mLaunchingProviders.size();
10769                int i;
10770                for (i = 0; i < N; i++) {
10771                    if (mLaunchingProviders.get(i) == cpr) {
10772                        break;
10773                    }
10774                }
10775
10776                // If the provider is not already being launched, then get it
10777                // started.
10778                if (i >= N) {
10779                    final long origId = Binder.clearCallingIdentity();
10780
10781                    try {
10782                        // Content provider is now in use, its package can't be stopped.
10783                        try {
10784                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10785                            AppGlobals.getPackageManager().setPackageStoppedState(
10786                                    cpr.appInfo.packageName, false, userId);
10787                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10788                        } catch (RemoteException e) {
10789                        } catch (IllegalArgumentException e) {
10790                            Slog.w(TAG, "Failed trying to unstop package "
10791                                    + cpr.appInfo.packageName + ": " + e);
10792                        }
10793
10794                        // Use existing process if already started
10795                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10796                        ProcessRecord proc = getProcessRecordLocked(
10797                                cpi.processName, cpr.appInfo.uid, false);
10798                        if (proc != null && proc.thread != null) {
10799                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10800                                    "Installing in existing process " + proc);
10801                            if (!proc.pubProviders.containsKey(cpi.name)) {
10802                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10803                                proc.pubProviders.put(cpi.name, cpr);
10804                                try {
10805                                    proc.thread.scheduleInstallProvider(cpi);
10806                                } catch (RemoteException e) {
10807                                }
10808                            }
10809                        } else {
10810                            checkTime(startTime, "getContentProviderImpl: before start process");
10811                            proc = startProcessLocked(cpi.processName,
10812                                    cpr.appInfo, false, 0, "content provider",
10813                                    new ComponentName(cpi.applicationInfo.packageName,
10814                                            cpi.name), false, false, false);
10815                            checkTime(startTime, "getContentProviderImpl: after start process");
10816                            if (proc == null) {
10817                                Slog.w(TAG, "Unable to launch app "
10818                                        + cpi.applicationInfo.packageName + "/"
10819                                        + cpi.applicationInfo.uid + " for provider "
10820                                        + name + ": process is bad");
10821                                return null;
10822                            }
10823                        }
10824                        cpr.launchingApp = proc;
10825                        mLaunchingProviders.add(cpr);
10826                    } finally {
10827                        Binder.restoreCallingIdentity(origId);
10828                    }
10829                }
10830
10831                checkTime(startTime, "getContentProviderImpl: updating data structures");
10832
10833                // Make sure the provider is published (the same provider class
10834                // may be published under multiple names).
10835                if (firstClass) {
10836                    mProviderMap.putProviderByClass(comp, cpr);
10837                }
10838
10839                mProviderMap.putProviderByName(name, cpr);
10840                conn = incProviderCountLocked(r, cpr, token, stable);
10841                if (conn != null) {
10842                    conn.waiting = true;
10843                }
10844            }
10845            checkTime(startTime, "getContentProviderImpl: done!");
10846        }
10847
10848        // Wait for the provider to be published...
10849        synchronized (cpr) {
10850            while (cpr.provider == null) {
10851                if (cpr.launchingApp == null) {
10852                    Slog.w(TAG, "Unable to launch app "
10853                            + cpi.applicationInfo.packageName + "/"
10854                            + cpi.applicationInfo.uid + " for provider "
10855                            + name + ": launching app became null");
10856                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10857                            UserHandle.getUserId(cpi.applicationInfo.uid),
10858                            cpi.applicationInfo.packageName,
10859                            cpi.applicationInfo.uid, name);
10860                    return null;
10861                }
10862                try {
10863                    if (DEBUG_MU) Slog.v(TAG_MU,
10864                            "Waiting to start provider " + cpr
10865                            + " launchingApp=" + cpr.launchingApp);
10866                    if (conn != null) {
10867                        conn.waiting = true;
10868                    }
10869                    cpr.wait();
10870                } catch (InterruptedException ex) {
10871                } finally {
10872                    if (conn != null) {
10873                        conn.waiting = false;
10874                    }
10875                }
10876            }
10877        }
10878        return cpr != null ? cpr.newHolder(conn) : null;
10879    }
10880
10881    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10882            ProcessRecord r, final int userId) {
10883        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10884                cpi.packageName, userId)) {
10885
10886            final boolean callerForeground = r == null || r.setSchedGroup
10887                    != ProcessList.SCHED_GROUP_BACKGROUND;
10888
10889            // Show a permission review UI only for starting from a foreground app
10890            if (!callerForeground) {
10891                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10892                        + cpi.packageName + " requires a permissions review");
10893                return false;
10894            }
10895
10896            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10897            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10898                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10899            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10900
10901            if (DEBUG_PERMISSIONS_REVIEW) {
10902                Slog.i(TAG, "u" + userId + " Launching permission review "
10903                        + "for package " + cpi.packageName);
10904            }
10905
10906            final UserHandle userHandle = new UserHandle(userId);
10907            mHandler.post(new Runnable() {
10908                @Override
10909                public void run() {
10910                    mContext.startActivityAsUser(intent, userHandle);
10911                }
10912            });
10913
10914            return false;
10915        }
10916
10917        return true;
10918    }
10919
10920    PackageManagerInternal getPackageManagerInternalLocked() {
10921        if (mPackageManagerInt == null) {
10922            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10923        }
10924        return mPackageManagerInt;
10925    }
10926
10927    @Override
10928    public final ContentProviderHolder getContentProvider(
10929            IApplicationThread caller, String name, int userId, boolean stable) {
10930        enforceNotIsolatedCaller("getContentProvider");
10931        if (caller == null) {
10932            String msg = "null IApplicationThread when getting content provider "
10933                    + name;
10934            Slog.w(TAG, msg);
10935            throw new SecurityException(msg);
10936        }
10937        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10938        // with cross-user grant.
10939        return getContentProviderImpl(caller, name, null, stable, userId);
10940    }
10941
10942    public ContentProviderHolder getContentProviderExternal(
10943            String name, int userId, IBinder token) {
10944        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10945            "Do not have permission in call getContentProviderExternal()");
10946        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10947                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10948        return getContentProviderExternalUnchecked(name, token, userId);
10949    }
10950
10951    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10952            IBinder token, int userId) {
10953        return getContentProviderImpl(null, name, token, true, userId);
10954    }
10955
10956    /**
10957     * Drop a content provider from a ProcessRecord's bookkeeping
10958     */
10959    public void removeContentProvider(IBinder connection, boolean stable) {
10960        enforceNotIsolatedCaller("removeContentProvider");
10961        long ident = Binder.clearCallingIdentity();
10962        try {
10963            synchronized (this) {
10964                ContentProviderConnection conn;
10965                try {
10966                    conn = (ContentProviderConnection)connection;
10967                } catch (ClassCastException e) {
10968                    String msg ="removeContentProvider: " + connection
10969                            + " not a ContentProviderConnection";
10970                    Slog.w(TAG, msg);
10971                    throw new IllegalArgumentException(msg);
10972                }
10973                if (conn == null) {
10974                    throw new NullPointerException("connection is null");
10975                }
10976                if (decProviderCountLocked(conn, null, null, stable)) {
10977                    updateOomAdjLocked();
10978                }
10979            }
10980        } finally {
10981            Binder.restoreCallingIdentity(ident);
10982        }
10983    }
10984
10985    public void removeContentProviderExternal(String name, IBinder token) {
10986        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10987            "Do not have permission in call removeContentProviderExternal()");
10988        int userId = UserHandle.getCallingUserId();
10989        long ident = Binder.clearCallingIdentity();
10990        try {
10991            removeContentProviderExternalUnchecked(name, token, userId);
10992        } finally {
10993            Binder.restoreCallingIdentity(ident);
10994        }
10995    }
10996
10997    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10998        synchronized (this) {
10999            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11000            if(cpr == null) {
11001                //remove from mProvidersByClass
11002                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11003                return;
11004            }
11005
11006            //update content provider record entry info
11007            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11008            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11009            if (localCpr.hasExternalProcessHandles()) {
11010                if (localCpr.removeExternalProcessHandleLocked(token)) {
11011                    updateOomAdjLocked();
11012                } else {
11013                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11014                            + " with no external reference for token: "
11015                            + token + ".");
11016                }
11017            } else {
11018                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11019                        + " with no external references.");
11020            }
11021        }
11022    }
11023
11024    public final void publishContentProviders(IApplicationThread caller,
11025            List<ContentProviderHolder> providers) {
11026        if (providers == null) {
11027            return;
11028        }
11029
11030        enforceNotIsolatedCaller("publishContentProviders");
11031        synchronized (this) {
11032            final ProcessRecord r = getRecordForAppLocked(caller);
11033            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11034            if (r == null) {
11035                throw new SecurityException(
11036                        "Unable to find app for caller " + caller
11037                      + " (pid=" + Binder.getCallingPid()
11038                      + ") when publishing content providers");
11039            }
11040
11041            final long origId = Binder.clearCallingIdentity();
11042
11043            final int N = providers.size();
11044            for (int i = 0; i < N; i++) {
11045                ContentProviderHolder src = providers.get(i);
11046                if (src == null || src.info == null || src.provider == null) {
11047                    continue;
11048                }
11049                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11050                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11051                if (dst != null) {
11052                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11053                    mProviderMap.putProviderByClass(comp, dst);
11054                    String names[] = dst.info.authority.split(";");
11055                    for (int j = 0; j < names.length; j++) {
11056                        mProviderMap.putProviderByName(names[j], dst);
11057                    }
11058
11059                    int launchingCount = mLaunchingProviders.size();
11060                    int j;
11061                    boolean wasInLaunchingProviders = false;
11062                    for (j = 0; j < launchingCount; j++) {
11063                        if (mLaunchingProviders.get(j) == dst) {
11064                            mLaunchingProviders.remove(j);
11065                            wasInLaunchingProviders = true;
11066                            j--;
11067                            launchingCount--;
11068                        }
11069                    }
11070                    if (wasInLaunchingProviders) {
11071                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11072                    }
11073                    synchronized (dst) {
11074                        dst.provider = src.provider;
11075                        dst.proc = r;
11076                        dst.notifyAll();
11077                    }
11078                    updateOomAdjLocked(r);
11079                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11080                            src.info.authority);
11081                }
11082            }
11083
11084            Binder.restoreCallingIdentity(origId);
11085        }
11086    }
11087
11088    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11089        ContentProviderConnection conn;
11090        try {
11091            conn = (ContentProviderConnection)connection;
11092        } catch (ClassCastException e) {
11093            String msg ="refContentProvider: " + connection
11094                    + " not a ContentProviderConnection";
11095            Slog.w(TAG, msg);
11096            throw new IllegalArgumentException(msg);
11097        }
11098        if (conn == null) {
11099            throw new NullPointerException("connection is null");
11100        }
11101
11102        synchronized (this) {
11103            if (stable > 0) {
11104                conn.numStableIncs += stable;
11105            }
11106            stable = conn.stableCount + stable;
11107            if (stable < 0) {
11108                throw new IllegalStateException("stableCount < 0: " + stable);
11109            }
11110
11111            if (unstable > 0) {
11112                conn.numUnstableIncs += unstable;
11113            }
11114            unstable = conn.unstableCount + unstable;
11115            if (unstable < 0) {
11116                throw new IllegalStateException("unstableCount < 0: " + unstable);
11117            }
11118
11119            if ((stable+unstable) <= 0) {
11120                throw new IllegalStateException("ref counts can't go to zero here: stable="
11121                        + stable + " unstable=" + unstable);
11122            }
11123            conn.stableCount = stable;
11124            conn.unstableCount = unstable;
11125            return !conn.dead;
11126        }
11127    }
11128
11129    public void unstableProviderDied(IBinder connection) {
11130        ContentProviderConnection conn;
11131        try {
11132            conn = (ContentProviderConnection)connection;
11133        } catch (ClassCastException e) {
11134            String msg ="refContentProvider: " + connection
11135                    + " not a ContentProviderConnection";
11136            Slog.w(TAG, msg);
11137            throw new IllegalArgumentException(msg);
11138        }
11139        if (conn == null) {
11140            throw new NullPointerException("connection is null");
11141        }
11142
11143        // Safely retrieve the content provider associated with the connection.
11144        IContentProvider provider;
11145        synchronized (this) {
11146            provider = conn.provider.provider;
11147        }
11148
11149        if (provider == null) {
11150            // Um, yeah, we're way ahead of you.
11151            return;
11152        }
11153
11154        // Make sure the caller is being honest with us.
11155        if (provider.asBinder().pingBinder()) {
11156            // Er, no, still looks good to us.
11157            synchronized (this) {
11158                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11159                        + " says " + conn + " died, but we don't agree");
11160                return;
11161            }
11162        }
11163
11164        // Well look at that!  It's dead!
11165        synchronized (this) {
11166            if (conn.provider.provider != provider) {
11167                // But something changed...  good enough.
11168                return;
11169            }
11170
11171            ProcessRecord proc = conn.provider.proc;
11172            if (proc == null || proc.thread == null) {
11173                // Seems like the process is already cleaned up.
11174                return;
11175            }
11176
11177            // As far as we're concerned, this is just like receiving a
11178            // death notification...  just a bit prematurely.
11179            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11180                    + ") early provider death");
11181            final long ident = Binder.clearCallingIdentity();
11182            try {
11183                appDiedLocked(proc);
11184            } finally {
11185                Binder.restoreCallingIdentity(ident);
11186            }
11187        }
11188    }
11189
11190    @Override
11191    public void appNotRespondingViaProvider(IBinder connection) {
11192        enforceCallingPermission(
11193                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11194
11195        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11196        if (conn == null) {
11197            Slog.w(TAG, "ContentProviderConnection is null");
11198            return;
11199        }
11200
11201        final ProcessRecord host = conn.provider.proc;
11202        if (host == null) {
11203            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11204            return;
11205        }
11206
11207        mHandler.post(new Runnable() {
11208            @Override
11209            public void run() {
11210                mAppErrors.appNotResponding(host, null, null, false,
11211                        "ContentProvider not responding");
11212            }
11213        });
11214    }
11215
11216    public final void installSystemProviders() {
11217        List<ProviderInfo> providers;
11218        synchronized (this) {
11219            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11220            providers = generateApplicationProvidersLocked(app);
11221            if (providers != null) {
11222                for (int i=providers.size()-1; i>=0; i--) {
11223                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11224                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11225                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11226                                + ": not system .apk");
11227                        providers.remove(i);
11228                    }
11229                }
11230            }
11231        }
11232        if (providers != null) {
11233            mSystemThread.installSystemProviders(providers);
11234        }
11235
11236        mCoreSettingsObserver = new CoreSettingsObserver(this);
11237        mFontScaleSettingObserver = new FontScaleSettingObserver();
11238
11239        //mUsageStatsService.monitorPackages();
11240    }
11241
11242    private void startPersistentApps(int matchFlags) {
11243        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11244
11245        synchronized (this) {
11246            try {
11247                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11248                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11249                for (ApplicationInfo app : apps) {
11250                    if (!"android".equals(app.packageName)) {
11251                        addAppLocked(app, false, null /* ABI override */);
11252                    }
11253                }
11254            } catch (RemoteException ex) {
11255            }
11256        }
11257    }
11258
11259    /**
11260     * When a user is unlocked, we need to install encryption-unaware providers
11261     * belonging to any running apps.
11262     */
11263    private void installEncryptionUnawareProviders(int userId) {
11264        // We're only interested in providers that are encryption unaware, and
11265        // we don't care about uninstalled apps, since there's no way they're
11266        // running at this point.
11267        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11268
11269        synchronized (this) {
11270            final int NP = mProcessNames.getMap().size();
11271            for (int ip = 0; ip < NP; ip++) {
11272                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11273                final int NA = apps.size();
11274                for (int ia = 0; ia < NA; ia++) {
11275                    final ProcessRecord app = apps.valueAt(ia);
11276                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11277
11278                    final int NG = app.pkgList.size();
11279                    for (int ig = 0; ig < NG; ig++) {
11280                        try {
11281                            final String pkgName = app.pkgList.keyAt(ig);
11282                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11283                                    .getPackageInfo(pkgName, matchFlags, userId);
11284                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11285                                for (ProviderInfo pi : pkgInfo.providers) {
11286                                    // TODO: keep in sync with generateApplicationProvidersLocked
11287                                    final boolean processMatch = Objects.equals(pi.processName,
11288                                            app.processName) || pi.multiprocess;
11289                                    final boolean userMatch = isSingleton(pi.processName,
11290                                            pi.applicationInfo, pi.name, pi.flags)
11291                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11292                                    if (processMatch && userMatch) {
11293                                        Log.v(TAG, "Installing " + pi);
11294                                        app.thread.scheduleInstallProvider(pi);
11295                                    } else {
11296                                        Log.v(TAG, "Skipping " + pi);
11297                                    }
11298                                }
11299                            }
11300                        } catch (RemoteException ignored) {
11301                        }
11302                    }
11303                }
11304            }
11305        }
11306    }
11307
11308    /**
11309     * Allows apps to retrieve the MIME type of a URI.
11310     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11311     * users, then it does not need permission to access the ContentProvider.
11312     * Either, it needs cross-user uri grants.
11313     *
11314     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11315     *
11316     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11317     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11318     */
11319    public String getProviderMimeType(Uri uri, int userId) {
11320        enforceNotIsolatedCaller("getProviderMimeType");
11321        final String name = uri.getAuthority();
11322        int callingUid = Binder.getCallingUid();
11323        int callingPid = Binder.getCallingPid();
11324        long ident = 0;
11325        boolean clearedIdentity = false;
11326        synchronized (this) {
11327            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11328        }
11329        if (canClearIdentity(callingPid, callingUid, userId)) {
11330            clearedIdentity = true;
11331            ident = Binder.clearCallingIdentity();
11332        }
11333        ContentProviderHolder holder = null;
11334        try {
11335            holder = getContentProviderExternalUnchecked(name, null, userId);
11336            if (holder != null) {
11337                return holder.provider.getType(uri);
11338            }
11339        } catch (RemoteException e) {
11340            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11341            return null;
11342        } catch (Exception e) {
11343            Log.w(TAG, "Exception while determining type of " + uri, e);
11344            return null;
11345        } finally {
11346            // We need to clear the identity to call removeContentProviderExternalUnchecked
11347            if (!clearedIdentity) {
11348                ident = Binder.clearCallingIdentity();
11349            }
11350            try {
11351                if (holder != null) {
11352                    removeContentProviderExternalUnchecked(name, null, userId);
11353                }
11354            } finally {
11355                Binder.restoreCallingIdentity(ident);
11356            }
11357        }
11358
11359        return null;
11360    }
11361
11362    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11363        if (UserHandle.getUserId(callingUid) == userId) {
11364            return true;
11365        }
11366        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11367                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11368                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11369                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11370                return true;
11371        }
11372        return false;
11373    }
11374
11375    // =========================================================
11376    // GLOBAL MANAGEMENT
11377    // =========================================================
11378
11379    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11380            boolean isolated, int isolatedUid) {
11381        String proc = customProcess != null ? customProcess : info.processName;
11382        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11383        final int userId = UserHandle.getUserId(info.uid);
11384        int uid = info.uid;
11385        if (isolated) {
11386            if (isolatedUid == 0) {
11387                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11388                while (true) {
11389                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11390                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11391                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11392                    }
11393                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11394                    mNextIsolatedProcessUid++;
11395                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11396                        // No process for this uid, use it.
11397                        break;
11398                    }
11399                    stepsLeft--;
11400                    if (stepsLeft <= 0) {
11401                        return null;
11402                    }
11403                }
11404            } else {
11405                // Special case for startIsolatedProcess (internal only), where
11406                // the uid of the isolated process is specified by the caller.
11407                uid = isolatedUid;
11408            }
11409        }
11410        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11411        if (!mBooted && !mBooting
11412                && userId == UserHandle.USER_SYSTEM
11413                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11414            r.persistent = true;
11415        }
11416        addProcessNameLocked(r);
11417        return r;
11418    }
11419
11420    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11421            String abiOverride) {
11422        ProcessRecord app;
11423        if (!isolated) {
11424            app = getProcessRecordLocked(info.processName, info.uid, true);
11425        } else {
11426            app = null;
11427        }
11428
11429        if (app == null) {
11430            app = newProcessRecordLocked(info, null, isolated, 0);
11431            updateLruProcessLocked(app, false, null);
11432            updateOomAdjLocked();
11433        }
11434
11435        // This package really, really can not be stopped.
11436        try {
11437            AppGlobals.getPackageManager().setPackageStoppedState(
11438                    info.packageName, false, UserHandle.getUserId(app.uid));
11439        } catch (RemoteException e) {
11440        } catch (IllegalArgumentException e) {
11441            Slog.w(TAG, "Failed trying to unstop package "
11442                    + info.packageName + ": " + e);
11443        }
11444
11445        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11446            app.persistent = true;
11447            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11448        }
11449        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11450            mPersistentStartingProcesses.add(app);
11451            startProcessLocked(app, "added application", app.processName, abiOverride,
11452                    null /* entryPoint */, null /* entryPointArgs */);
11453        }
11454
11455        return app;
11456    }
11457
11458    public void unhandledBack() {
11459        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11460                "unhandledBack()");
11461
11462        synchronized(this) {
11463            final long origId = Binder.clearCallingIdentity();
11464            try {
11465                getFocusedStack().unhandledBackLocked();
11466            } finally {
11467                Binder.restoreCallingIdentity(origId);
11468            }
11469        }
11470    }
11471
11472    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11473        enforceNotIsolatedCaller("openContentUri");
11474        final int userId = UserHandle.getCallingUserId();
11475        String name = uri.getAuthority();
11476        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11477        ParcelFileDescriptor pfd = null;
11478        if (cph != null) {
11479            // We record the binder invoker's uid in thread-local storage before
11480            // going to the content provider to open the file.  Later, in the code
11481            // that handles all permissions checks, we look for this uid and use
11482            // that rather than the Activity Manager's own uid.  The effect is that
11483            // we do the check against the caller's permissions even though it looks
11484            // to the content provider like the Activity Manager itself is making
11485            // the request.
11486            Binder token = new Binder();
11487            sCallerIdentity.set(new Identity(
11488                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11489            try {
11490                pfd = cph.provider.openFile(null, uri, "r", null, token);
11491            } catch (FileNotFoundException e) {
11492                // do nothing; pfd will be returned null
11493            } finally {
11494                // Ensure that whatever happens, we clean up the identity state
11495                sCallerIdentity.remove();
11496                // Ensure we're done with the provider.
11497                removeContentProviderExternalUnchecked(name, null, userId);
11498            }
11499        } else {
11500            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11501        }
11502        return pfd;
11503    }
11504
11505    // Actually is sleeping or shutting down or whatever else in the future
11506    // is an inactive state.
11507    boolean isSleepingOrShuttingDownLocked() {
11508        return isSleepingLocked() || mShuttingDown;
11509    }
11510
11511    boolean isShuttingDownLocked() {
11512        return mShuttingDown;
11513    }
11514
11515    boolean isSleepingLocked() {
11516        return mSleeping;
11517    }
11518
11519    void onWakefulnessChanged(int wakefulness) {
11520        synchronized(this) {
11521            mWakefulness = wakefulness;
11522            updateSleepIfNeededLocked();
11523        }
11524    }
11525
11526    void finishRunningVoiceLocked() {
11527        if (mRunningVoice != null) {
11528            mRunningVoice = null;
11529            mVoiceWakeLock.release();
11530            updateSleepIfNeededLocked();
11531        }
11532    }
11533
11534    void startTimeTrackingFocusedActivityLocked() {
11535        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11536            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11537        }
11538    }
11539
11540    void updateSleepIfNeededLocked() {
11541        if (mSleeping && !shouldSleepLocked()) {
11542            mSleeping = false;
11543            startTimeTrackingFocusedActivityLocked();
11544            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11545            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11546            updateOomAdjLocked();
11547        } else if (!mSleeping && shouldSleepLocked()) {
11548            mSleeping = true;
11549            if (mCurAppTimeTracker != null) {
11550                mCurAppTimeTracker.stop();
11551            }
11552            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11553            mStackSupervisor.goingToSleepLocked();
11554            updateOomAdjLocked();
11555
11556            // Initialize the wake times of all processes.
11557            checkExcessivePowerUsageLocked(false);
11558            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11559            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11560            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11561        }
11562    }
11563
11564    private boolean shouldSleepLocked() {
11565        // Resume applications while running a voice interactor.
11566        if (mRunningVoice != null) {
11567            return false;
11568        }
11569
11570        // TODO: Transform the lock screen state into a sleep token instead.
11571        switch (mWakefulness) {
11572            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11573            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11574            case PowerManagerInternal.WAKEFULNESS_DOZING:
11575                // Pause applications whenever the lock screen is shown or any sleep
11576                // tokens have been acquired.
11577                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11578            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11579            default:
11580                // If we're asleep then pause applications unconditionally.
11581                return true;
11582        }
11583    }
11584
11585    /** Pokes the task persister. */
11586    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11587        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11588    }
11589
11590    /** Notifies all listeners when the task stack has changed. */
11591    void notifyTaskStackChangedLocked() {
11592        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11593        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11594        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11595        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11596    }
11597
11598    /** Notifies all listeners when an Activity is pinned. */
11599    void notifyActivityPinnedLocked() {
11600        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11601        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11602    }
11603
11604    /**
11605     * Notifies all listeners when an attempt was made to start an an activity that is already
11606     * running in the pinned stack and the activity was not actually started, but the task is
11607     * either brought to the front or a new Intent is delivered to it.
11608     */
11609    void notifyPinnedActivityRestartAttemptLocked() {
11610        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11611        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11612    }
11613
11614    /** Notifies all listeners when the pinned stack animation ends. */
11615    @Override
11616    public void notifyPinnedStackAnimationEnded() {
11617        synchronized (this) {
11618            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11619            mHandler.obtainMessage(
11620                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11621        }
11622    }
11623
11624    @Override
11625    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11626        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11627    }
11628
11629    @Override
11630    public boolean shutdown(int timeout) {
11631        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11632                != PackageManager.PERMISSION_GRANTED) {
11633            throw new SecurityException("Requires permission "
11634                    + android.Manifest.permission.SHUTDOWN);
11635        }
11636
11637        boolean timedout = false;
11638
11639        synchronized(this) {
11640            mShuttingDown = true;
11641            updateEventDispatchingLocked();
11642            timedout = mStackSupervisor.shutdownLocked(timeout);
11643        }
11644
11645        mAppOpsService.shutdown();
11646        if (mUsageStatsService != null) {
11647            mUsageStatsService.prepareShutdown();
11648        }
11649        mBatteryStatsService.shutdown();
11650        synchronized (this) {
11651            mProcessStats.shutdownLocked();
11652            notifyTaskPersisterLocked(null, true);
11653        }
11654
11655        return timedout;
11656    }
11657
11658    public final void activitySlept(IBinder token) {
11659        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11660
11661        final long origId = Binder.clearCallingIdentity();
11662
11663        synchronized (this) {
11664            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11665            if (r != null) {
11666                mStackSupervisor.activitySleptLocked(r);
11667            }
11668        }
11669
11670        Binder.restoreCallingIdentity(origId);
11671    }
11672
11673    private String lockScreenShownToString() {
11674        switch (mLockScreenShown) {
11675            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11676            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11677            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11678            default: return "Unknown=" + mLockScreenShown;
11679        }
11680    }
11681
11682    void logLockScreen(String msg) {
11683        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11684                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11685                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11686                + " mSleeping=" + mSleeping);
11687    }
11688
11689    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11690        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11691        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11692        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11693            boolean wasRunningVoice = mRunningVoice != null;
11694            mRunningVoice = session;
11695            if (!wasRunningVoice) {
11696                mVoiceWakeLock.acquire();
11697                updateSleepIfNeededLocked();
11698            }
11699        }
11700    }
11701
11702    private void updateEventDispatchingLocked() {
11703        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11704    }
11705
11706    public void setLockScreenShown(boolean showing, boolean occluded) {
11707        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11708                != PackageManager.PERMISSION_GRANTED) {
11709            throw new SecurityException("Requires permission "
11710                    + android.Manifest.permission.DEVICE_POWER);
11711        }
11712
11713        synchronized(this) {
11714            long ident = Binder.clearCallingIdentity();
11715            try {
11716                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11717                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11718                if (showing && occluded) {
11719                    // The lock screen is currently showing, but is occluded by a window that can
11720                    // show on top of the lock screen. In this can we want to dismiss the docked
11721                    // stack since it will be complicated/risky to try to put the activity on top
11722                    // of the lock screen in the right fullscreen configuration.
11723                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11724                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11725                }
11726
11727                updateSleepIfNeededLocked();
11728            } finally {
11729                Binder.restoreCallingIdentity(ident);
11730            }
11731        }
11732    }
11733
11734    @Override
11735    public void notifyLockedProfile(@UserIdInt int userId) {
11736        try {
11737            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11738                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11739            }
11740        } catch (RemoteException ex) {
11741            throw new SecurityException("Fail to check is caller a privileged app", ex);
11742        }
11743
11744        synchronized (this) {
11745            if (mStackSupervisor.isUserLockedProfile(userId)) {
11746                final long ident = Binder.clearCallingIdentity();
11747                try {
11748                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11749                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11750                        // If there is no device lock, we will show the profile's credential page.
11751                        mActivityStarter.showConfirmDeviceCredential(userId);
11752                    } else {
11753                        // Showing launcher to avoid user entering credential twice.
11754                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11755                    }
11756                } finally {
11757                    Binder.restoreCallingIdentity(ident);
11758                }
11759            }
11760        }
11761    }
11762
11763    @Override
11764    public void startConfirmDeviceCredentialIntent(Intent intent) {
11765        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11766        synchronized (this) {
11767            final long ident = Binder.clearCallingIdentity();
11768            try {
11769                mActivityStarter.startConfirmCredentialIntent(intent);
11770            } finally {
11771                Binder.restoreCallingIdentity(ident);
11772            }
11773        }
11774    }
11775
11776    @Override
11777    public void stopAppSwitches() {
11778        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11779                != PackageManager.PERMISSION_GRANTED) {
11780            throw new SecurityException("viewquires permission "
11781                    + android.Manifest.permission.STOP_APP_SWITCHES);
11782        }
11783
11784        synchronized(this) {
11785            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11786                    + APP_SWITCH_DELAY_TIME;
11787            mDidAppSwitch = false;
11788            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11789            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11790            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11791        }
11792    }
11793
11794    public void resumeAppSwitches() {
11795        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11796                != PackageManager.PERMISSION_GRANTED) {
11797            throw new SecurityException("Requires permission "
11798                    + android.Manifest.permission.STOP_APP_SWITCHES);
11799        }
11800
11801        synchronized(this) {
11802            // Note that we don't execute any pending app switches... we will
11803            // let those wait until either the timeout, or the next start
11804            // activity request.
11805            mAppSwitchesAllowedTime = 0;
11806        }
11807    }
11808
11809    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11810            int callingPid, int callingUid, String name) {
11811        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11812            return true;
11813        }
11814
11815        int perm = checkComponentPermission(
11816                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11817                sourceUid, -1, true);
11818        if (perm == PackageManager.PERMISSION_GRANTED) {
11819            return true;
11820        }
11821
11822        // If the actual IPC caller is different from the logical source, then
11823        // also see if they are allowed to control app switches.
11824        if (callingUid != -1 && callingUid != sourceUid) {
11825            perm = checkComponentPermission(
11826                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11827                    callingUid, -1, true);
11828            if (perm == PackageManager.PERMISSION_GRANTED) {
11829                return true;
11830            }
11831        }
11832
11833        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11834        return false;
11835    }
11836
11837    public void setDebugApp(String packageName, boolean waitForDebugger,
11838            boolean persistent) {
11839        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11840                "setDebugApp()");
11841
11842        long ident = Binder.clearCallingIdentity();
11843        try {
11844            // Note that this is not really thread safe if there are multiple
11845            // callers into it at the same time, but that's not a situation we
11846            // care about.
11847            if (persistent) {
11848                final ContentResolver resolver = mContext.getContentResolver();
11849                Settings.Global.putString(
11850                    resolver, Settings.Global.DEBUG_APP,
11851                    packageName);
11852                Settings.Global.putInt(
11853                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11854                    waitForDebugger ? 1 : 0);
11855            }
11856
11857            synchronized (this) {
11858                if (!persistent) {
11859                    mOrigDebugApp = mDebugApp;
11860                    mOrigWaitForDebugger = mWaitForDebugger;
11861                }
11862                mDebugApp = packageName;
11863                mWaitForDebugger = waitForDebugger;
11864                mDebugTransient = !persistent;
11865                if (packageName != null) {
11866                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11867                            false, UserHandle.USER_ALL, "set debug app");
11868                }
11869            }
11870        } finally {
11871            Binder.restoreCallingIdentity(ident);
11872        }
11873    }
11874
11875    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11876        synchronized (this) {
11877            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11878            if (!isDebuggable) {
11879                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11880                    throw new SecurityException("Process not debuggable: " + app.packageName);
11881                }
11882            }
11883
11884            mTrackAllocationApp = processName;
11885        }
11886    }
11887
11888    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11889        synchronized (this) {
11890            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11891            if (!isDebuggable) {
11892                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11893                    throw new SecurityException("Process not debuggable: " + app.packageName);
11894                }
11895            }
11896            mProfileApp = processName;
11897            mProfileFile = profilerInfo.profileFile;
11898            if (mProfileFd != null) {
11899                try {
11900                    mProfileFd.close();
11901                } catch (IOException e) {
11902                }
11903                mProfileFd = null;
11904            }
11905            mProfileFd = profilerInfo.profileFd;
11906            mSamplingInterval = profilerInfo.samplingInterval;
11907            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11908            mProfileType = 0;
11909        }
11910    }
11911
11912    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
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        mNativeDebuggingApp = processName;
11920    }
11921
11922    @Override
11923    public void setAlwaysFinish(boolean enabled) {
11924        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11925                "setAlwaysFinish()");
11926
11927        long ident = Binder.clearCallingIdentity();
11928        try {
11929            Settings.Global.putInt(
11930                    mContext.getContentResolver(),
11931                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11932
11933            synchronized (this) {
11934                mAlwaysFinishActivities = enabled;
11935            }
11936        } finally {
11937            Binder.restoreCallingIdentity(ident);
11938        }
11939    }
11940
11941    @Override
11942    public void setLenientBackgroundCheck(boolean enabled) {
11943        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11944                "setLenientBackgroundCheck()");
11945
11946        long ident = Binder.clearCallingIdentity();
11947        try {
11948            Settings.Global.putInt(
11949                    mContext.getContentResolver(),
11950                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11951
11952            synchronized (this) {
11953                mLenientBackgroundCheck = enabled;
11954            }
11955        } finally {
11956            Binder.restoreCallingIdentity(ident);
11957        }
11958    }
11959
11960    @Override
11961    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11962        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11963                "setActivityController()");
11964        synchronized (this) {
11965            mController = controller;
11966            mControllerIsAMonkey = imAMonkey;
11967            Watchdog.getInstance().setActivityController(controller);
11968        }
11969    }
11970
11971    @Override
11972    public void setUserIsMonkey(boolean userIsMonkey) {
11973        synchronized (this) {
11974            synchronized (mPidsSelfLocked) {
11975                final int callingPid = Binder.getCallingPid();
11976                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11977                if (precessRecord == null) {
11978                    throw new SecurityException("Unknown process: " + callingPid);
11979                }
11980                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11981                    throw new SecurityException("Only an instrumentation process "
11982                            + "with a UiAutomation can call setUserIsMonkey");
11983                }
11984            }
11985            mUserIsMonkey = userIsMonkey;
11986        }
11987    }
11988
11989    @Override
11990    public boolean isUserAMonkey() {
11991        synchronized (this) {
11992            // If there is a controller also implies the user is a monkey.
11993            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11994        }
11995    }
11996
11997    public void requestBugReport(int bugreportType) {
11998        String service = null;
11999        switch (bugreportType) {
12000            case ActivityManager.BUGREPORT_OPTION_FULL:
12001                service = "bugreport";
12002                break;
12003            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12004                service = "bugreportplus";
12005                break;
12006            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12007                service = "bugreportremote";
12008                break;
12009        }
12010        if (service == null) {
12011            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12012                    + bugreportType);
12013        }
12014        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12015        SystemProperties.set("ctl.start", service);
12016    }
12017
12018    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12019        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12020    }
12021
12022    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12023        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12024            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12025        }
12026        return KEY_DISPATCHING_TIMEOUT;
12027    }
12028
12029    @Override
12030    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12031        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12032                != PackageManager.PERMISSION_GRANTED) {
12033            throw new SecurityException("Requires permission "
12034                    + android.Manifest.permission.FILTER_EVENTS);
12035        }
12036        ProcessRecord proc;
12037        long timeout;
12038        synchronized (this) {
12039            synchronized (mPidsSelfLocked) {
12040                proc = mPidsSelfLocked.get(pid);
12041            }
12042            timeout = getInputDispatchingTimeoutLocked(proc);
12043        }
12044
12045        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12046            return -1;
12047        }
12048
12049        return timeout;
12050    }
12051
12052    /**
12053     * Handle input dispatching timeouts.
12054     * Returns whether input dispatching should be aborted or not.
12055     */
12056    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12057            final ActivityRecord activity, final ActivityRecord parent,
12058            final boolean aboveSystem, String reason) {
12059        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12060                != PackageManager.PERMISSION_GRANTED) {
12061            throw new SecurityException("Requires permission "
12062                    + android.Manifest.permission.FILTER_EVENTS);
12063        }
12064
12065        final String annotation;
12066        if (reason == null) {
12067            annotation = "Input dispatching timed out";
12068        } else {
12069            annotation = "Input dispatching timed out (" + reason + ")";
12070        }
12071
12072        if (proc != null) {
12073            synchronized (this) {
12074                if (proc.debugging) {
12075                    return false;
12076                }
12077
12078                if (mDidDexOpt) {
12079                    // Give more time since we were dexopting.
12080                    mDidDexOpt = false;
12081                    return false;
12082                }
12083
12084                if (proc.instrumentationClass != null) {
12085                    Bundle info = new Bundle();
12086                    info.putString("shortMsg", "keyDispatchingTimedOut");
12087                    info.putString("longMsg", annotation);
12088                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12089                    return true;
12090                }
12091            }
12092            mHandler.post(new Runnable() {
12093                @Override
12094                public void run() {
12095                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12096                }
12097            });
12098        }
12099
12100        return true;
12101    }
12102
12103    @Override
12104    public Bundle getAssistContextExtras(int requestType) {
12105        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12106                null, null, true /* focused */, true /* newSessionId */,
12107                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12108        if (pae == null) {
12109            return null;
12110        }
12111        synchronized (pae) {
12112            while (!pae.haveResult) {
12113                try {
12114                    pae.wait();
12115                } catch (InterruptedException e) {
12116                }
12117            }
12118        }
12119        synchronized (this) {
12120            buildAssistBundleLocked(pae, pae.result);
12121            mPendingAssistExtras.remove(pae);
12122            mUiHandler.removeCallbacks(pae);
12123        }
12124        return pae.extras;
12125    }
12126
12127    @Override
12128    public boolean isAssistDataAllowedOnCurrentActivity() {
12129        int userId;
12130        synchronized (this) {
12131            userId = mUserController.getCurrentUserIdLocked();
12132            ActivityRecord activity = getFocusedStack().topActivity();
12133            if (activity == null) {
12134                return false;
12135            }
12136            userId = activity.userId;
12137        }
12138        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12139                Context.DEVICE_POLICY_SERVICE);
12140        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12141    }
12142
12143    @Override
12144    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12145        long ident = Binder.clearCallingIdentity();
12146        try {
12147            synchronized (this) {
12148                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12149                ActivityRecord top = getFocusedStack().topActivity();
12150                if (top != caller) {
12151                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12152                            + " is not current top " + top);
12153                    return false;
12154                }
12155                if (!top.nowVisible) {
12156                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12157                            + " is not visible");
12158                    return false;
12159                }
12160            }
12161            AssistUtils utils = new AssistUtils(mContext);
12162            return utils.showSessionForActiveService(args,
12163                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12164        } finally {
12165            Binder.restoreCallingIdentity(ident);
12166        }
12167    }
12168
12169    @Override
12170    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12171            Bundle receiverExtras,
12172            IBinder activityToken, boolean focused, boolean newSessionId) {
12173        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12174                activityToken, focused, newSessionId,
12175                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12176                != null;
12177    }
12178
12179    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12180            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12181            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12182        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12183                "enqueueAssistContext()");
12184        synchronized (this) {
12185            ActivityRecord activity = getFocusedStack().topActivity();
12186            if (activity == null) {
12187                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12188                return null;
12189            }
12190            if (activity.app == null || activity.app.thread == null) {
12191                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12192                return null;
12193            }
12194            if (focused) {
12195                if (activityToken != null) {
12196                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12197                    if (activity != caller) {
12198                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12199                                + " is not current top " + activity);
12200                        return null;
12201                    }
12202                }
12203            } else {
12204                activity = ActivityRecord.forTokenLocked(activityToken);
12205                if (activity == null) {
12206                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12207                            + " couldn't be found");
12208                    return null;
12209                }
12210            }
12211
12212            PendingAssistExtras pae;
12213            Bundle extras = new Bundle();
12214            if (args != null) {
12215                extras.putAll(args);
12216            }
12217            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12218            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12219            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12220                    userHandle);
12221            // Increment the sessionId if necessary
12222            if (newSessionId) {
12223                mViSessionId++;
12224            }
12225            try {
12226                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12227                        requestType, mViSessionId);
12228                mPendingAssistExtras.add(pae);
12229                mUiHandler.postDelayed(pae, timeout);
12230            } catch (RemoteException e) {
12231                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12232                return null;
12233            }
12234            return pae;
12235        }
12236    }
12237
12238    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12239        IResultReceiver receiver;
12240        synchronized (this) {
12241            mPendingAssistExtras.remove(pae);
12242            receiver = pae.receiver;
12243        }
12244        if (receiver != null) {
12245            // Caller wants result sent back to them.
12246            Bundle sendBundle = new Bundle();
12247            // At least return the receiver extras
12248            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12249                    pae.receiverExtras);
12250            try {
12251                pae.receiver.send(0, sendBundle);
12252            } catch (RemoteException e) {
12253            }
12254        }
12255    }
12256
12257    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12258        if (result != null) {
12259            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12260        }
12261        if (pae.hint != null) {
12262            pae.extras.putBoolean(pae.hint, true);
12263        }
12264    }
12265
12266    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12267            AssistContent content, Uri referrer) {
12268        PendingAssistExtras pae = (PendingAssistExtras)token;
12269        synchronized (pae) {
12270            pae.result = extras;
12271            pae.structure = structure;
12272            pae.content = content;
12273            if (referrer != null) {
12274                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12275            }
12276            pae.haveResult = true;
12277            pae.notifyAll();
12278            if (pae.intent == null && pae.receiver == null) {
12279                // Caller is just waiting for the result.
12280                return;
12281            }
12282        }
12283
12284        // We are now ready to launch the assist activity.
12285        IResultReceiver sendReceiver = null;
12286        Bundle sendBundle = null;
12287        synchronized (this) {
12288            buildAssistBundleLocked(pae, extras);
12289            boolean exists = mPendingAssistExtras.remove(pae);
12290            mUiHandler.removeCallbacks(pae);
12291            if (!exists) {
12292                // Timed out.
12293                return;
12294            }
12295            if ((sendReceiver=pae.receiver) != null) {
12296                // Caller wants result sent back to them.
12297                sendBundle = new Bundle();
12298                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12299                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12300                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12301                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12302                        pae.receiverExtras);
12303            }
12304        }
12305        if (sendReceiver != null) {
12306            try {
12307                sendReceiver.send(0, sendBundle);
12308            } catch (RemoteException e) {
12309            }
12310            return;
12311        }
12312
12313        long ident = Binder.clearCallingIdentity();
12314        try {
12315            pae.intent.replaceExtras(pae.extras);
12316            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12317                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12318                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12319            closeSystemDialogs("assist");
12320            try {
12321                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12322            } catch (ActivityNotFoundException e) {
12323                Slog.w(TAG, "No activity to handle assist action.", e);
12324            }
12325        } finally {
12326            Binder.restoreCallingIdentity(ident);
12327        }
12328    }
12329
12330    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12331            Bundle args) {
12332        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12333                true /* focused */, true /* newSessionId */,
12334                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12335    }
12336
12337    public void registerProcessObserver(IProcessObserver observer) {
12338        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12339                "registerProcessObserver()");
12340        synchronized (this) {
12341            mProcessObservers.register(observer);
12342        }
12343    }
12344
12345    @Override
12346    public void unregisterProcessObserver(IProcessObserver observer) {
12347        synchronized (this) {
12348            mProcessObservers.unregister(observer);
12349        }
12350    }
12351
12352    @Override
12353    public void registerUidObserver(IUidObserver observer, int which) {
12354        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12355                "registerUidObserver()");
12356        synchronized (this) {
12357            mUidObservers.register(observer, which);
12358        }
12359    }
12360
12361    @Override
12362    public void unregisterUidObserver(IUidObserver observer) {
12363        synchronized (this) {
12364            mUidObservers.unregister(observer);
12365        }
12366    }
12367
12368    @Override
12369    public boolean convertFromTranslucent(IBinder token) {
12370        final long origId = Binder.clearCallingIdentity();
12371        try {
12372            synchronized (this) {
12373                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12374                if (r == null) {
12375                    return false;
12376                }
12377                final boolean translucentChanged = r.changeWindowTranslucency(true);
12378                if (translucentChanged) {
12379                    r.task.stack.releaseBackgroundResources(r);
12380                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12381                }
12382                mWindowManager.setAppFullscreen(token, true);
12383                return translucentChanged;
12384            }
12385        } finally {
12386            Binder.restoreCallingIdentity(origId);
12387        }
12388    }
12389
12390    @Override
12391    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12392        final long origId = Binder.clearCallingIdentity();
12393        try {
12394            synchronized (this) {
12395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12396                if (r == null) {
12397                    return false;
12398                }
12399                int index = r.task.mActivities.lastIndexOf(r);
12400                if (index > 0) {
12401                    ActivityRecord under = r.task.mActivities.get(index - 1);
12402                    under.returningOptions = options;
12403                }
12404                final boolean translucentChanged = r.changeWindowTranslucency(false);
12405                if (translucentChanged) {
12406                    r.task.stack.convertActivityToTranslucent(r);
12407                }
12408                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12409                mWindowManager.setAppFullscreen(token, false);
12410                return translucentChanged;
12411            }
12412        } finally {
12413            Binder.restoreCallingIdentity(origId);
12414        }
12415    }
12416
12417    @Override
12418    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12419        final long origId = Binder.clearCallingIdentity();
12420        try {
12421            synchronized (this) {
12422                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12423                if (r != null) {
12424                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12425                }
12426            }
12427            return false;
12428        } finally {
12429            Binder.restoreCallingIdentity(origId);
12430        }
12431    }
12432
12433    @Override
12434    public boolean isBackgroundVisibleBehind(IBinder token) {
12435        final long origId = Binder.clearCallingIdentity();
12436        try {
12437            synchronized (this) {
12438                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12439                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12440                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12441                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12442                return visible;
12443            }
12444        } finally {
12445            Binder.restoreCallingIdentity(origId);
12446        }
12447    }
12448
12449    @Override
12450    public ActivityOptions getActivityOptions(IBinder token) {
12451        final long origId = Binder.clearCallingIdentity();
12452        try {
12453            synchronized (this) {
12454                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12455                if (r != null) {
12456                    final ActivityOptions activityOptions = r.pendingOptions;
12457                    r.pendingOptions = null;
12458                    return activityOptions;
12459                }
12460                return null;
12461            }
12462        } finally {
12463            Binder.restoreCallingIdentity(origId);
12464        }
12465    }
12466
12467    @Override
12468    public void setImmersive(IBinder token, boolean immersive) {
12469        synchronized(this) {
12470            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12471            if (r == null) {
12472                throw new IllegalArgumentException();
12473            }
12474            r.immersive = immersive;
12475
12476            // update associated state if we're frontmost
12477            if (r == mFocusedActivity) {
12478                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12479                applyUpdateLockStateLocked(r);
12480            }
12481        }
12482    }
12483
12484    @Override
12485    public boolean isImmersive(IBinder token) {
12486        synchronized (this) {
12487            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12488            if (r == null) {
12489                throw new IllegalArgumentException();
12490            }
12491            return r.immersive;
12492        }
12493    }
12494
12495    @Override
12496    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12497        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12498            throw new UnsupportedOperationException("VR mode not supported on this device!");
12499        }
12500
12501        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12502
12503        ActivityRecord r;
12504        synchronized (this) {
12505            r = ActivityRecord.isInStackLocked(token);
12506        }
12507
12508        if (r == null) {
12509            throw new IllegalArgumentException();
12510        }
12511
12512        int err;
12513        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12514                VrManagerInternal.NO_ERROR) {
12515            return err;
12516        }
12517
12518        synchronized(this) {
12519            r.requestedVrComponent = (enabled) ? packageName : null;
12520
12521            // Update associated state if this activity is currently focused
12522            if (r == mFocusedActivity) {
12523                applyUpdateVrModeLocked(r);
12524            }
12525            return 0;
12526        }
12527    }
12528
12529    @Override
12530    public boolean isVrModePackageEnabled(ComponentName packageName) {
12531        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12532            throw new UnsupportedOperationException("VR mode not supported on this device!");
12533        }
12534
12535        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12536
12537        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12538                VrManagerInternal.NO_ERROR;
12539    }
12540
12541    public boolean isTopActivityImmersive() {
12542        enforceNotIsolatedCaller("startActivity");
12543        synchronized (this) {
12544            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12545            return (r != null) ? r.immersive : false;
12546        }
12547    }
12548
12549    @Override
12550    public boolean isTopOfTask(IBinder token) {
12551        synchronized (this) {
12552            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12553            if (r == null) {
12554                throw new IllegalArgumentException();
12555            }
12556            return r.task.getTopActivity() == r;
12557        }
12558    }
12559
12560    public final void enterSafeMode() {
12561        synchronized(this) {
12562            // It only makes sense to do this before the system is ready
12563            // and started launching other packages.
12564            if (!mSystemReady) {
12565                try {
12566                    AppGlobals.getPackageManager().enterSafeMode();
12567                } catch (RemoteException e) {
12568                }
12569            }
12570
12571            mSafeMode = true;
12572        }
12573    }
12574
12575    public final void showSafeModeOverlay() {
12576        View v = LayoutInflater.from(mContext).inflate(
12577                com.android.internal.R.layout.safe_mode, null);
12578        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12579        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12580        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12581        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12582        lp.gravity = Gravity.BOTTOM | Gravity.START;
12583        lp.format = v.getBackground().getOpacity();
12584        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12585                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12586        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12587        ((WindowManager)mContext.getSystemService(
12588                Context.WINDOW_SERVICE)).addView(v, lp);
12589    }
12590
12591    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12592        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12593            return;
12594        }
12595        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12596        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12597        synchronized (stats) {
12598            if (mBatteryStatsService.isOnBattery()) {
12599                mBatteryStatsService.enforceCallingPermission();
12600                int MY_UID = Binder.getCallingUid();
12601                final int uid;
12602                if (sender == null) {
12603                    uid = sourceUid;
12604                } else {
12605                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12606                }
12607                BatteryStatsImpl.Uid.Pkg pkg =
12608                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12609                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12610                pkg.noteWakeupAlarmLocked(tag);
12611            }
12612        }
12613    }
12614
12615    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12616        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12617            return;
12618        }
12619        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12620        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12621        synchronized (stats) {
12622            mBatteryStatsService.enforceCallingPermission();
12623            int MY_UID = Binder.getCallingUid();
12624            final int uid;
12625            if (sender == null) {
12626                uid = sourceUid;
12627            } else {
12628                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12629            }
12630            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12631        }
12632    }
12633
12634    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12635        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12636            return;
12637        }
12638        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12639        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12640        synchronized (stats) {
12641            mBatteryStatsService.enforceCallingPermission();
12642            int MY_UID = Binder.getCallingUid();
12643            final int uid;
12644            if (sender == null) {
12645                uid = sourceUid;
12646            } else {
12647                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12648            }
12649            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12650        }
12651    }
12652
12653    public boolean killPids(int[] pids, String pReason, boolean secure) {
12654        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12655            throw new SecurityException("killPids only available to the system");
12656        }
12657        String reason = (pReason == null) ? "Unknown" : pReason;
12658        // XXX Note: don't acquire main activity lock here, because the window
12659        // manager calls in with its locks held.
12660
12661        boolean killed = false;
12662        synchronized (mPidsSelfLocked) {
12663            int worstType = 0;
12664            for (int i=0; i<pids.length; i++) {
12665                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12666                if (proc != null) {
12667                    int type = proc.setAdj;
12668                    if (type > worstType) {
12669                        worstType = type;
12670                    }
12671                }
12672            }
12673
12674            // If the worst oom_adj is somewhere in the cached proc LRU range,
12675            // then constrain it so we will kill all cached procs.
12676            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12677                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12678                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12679            }
12680
12681            // If this is not a secure call, don't let it kill processes that
12682            // are important.
12683            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12684                worstType = ProcessList.SERVICE_ADJ;
12685            }
12686
12687            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12688            for (int i=0; i<pids.length; i++) {
12689                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12690                if (proc == null) {
12691                    continue;
12692                }
12693                int adj = proc.setAdj;
12694                if (adj >= worstType && !proc.killedByAm) {
12695                    proc.kill(reason, true);
12696                    killed = true;
12697                }
12698            }
12699        }
12700        return killed;
12701    }
12702
12703    @Override
12704    public void killUid(int appId, int userId, String reason) {
12705        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12706        synchronized (this) {
12707            final long identity = Binder.clearCallingIdentity();
12708            try {
12709                killPackageProcessesLocked(null, appId, userId,
12710                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12711                        reason != null ? reason : "kill uid");
12712            } finally {
12713                Binder.restoreCallingIdentity(identity);
12714            }
12715        }
12716    }
12717
12718    @Override
12719    public boolean killProcessesBelowForeground(String reason) {
12720        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12721            throw new SecurityException("killProcessesBelowForeground() only available to system");
12722        }
12723
12724        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12725    }
12726
12727    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12728        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12729            throw new SecurityException("killProcessesBelowAdj() only available to system");
12730        }
12731
12732        boolean killed = false;
12733        synchronized (mPidsSelfLocked) {
12734            final int size = mPidsSelfLocked.size();
12735            for (int i = 0; i < size; i++) {
12736                final int pid = mPidsSelfLocked.keyAt(i);
12737                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12738                if (proc == null) continue;
12739
12740                final int adj = proc.setAdj;
12741                if (adj > belowAdj && !proc.killedByAm) {
12742                    proc.kill(reason, true);
12743                    killed = true;
12744                }
12745            }
12746        }
12747        return killed;
12748    }
12749
12750    @Override
12751    public void hang(final IBinder who, boolean allowRestart) {
12752        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12753                != PackageManager.PERMISSION_GRANTED) {
12754            throw new SecurityException("Requires permission "
12755                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12756        }
12757
12758        final IBinder.DeathRecipient death = new DeathRecipient() {
12759            @Override
12760            public void binderDied() {
12761                synchronized (this) {
12762                    notifyAll();
12763                }
12764            }
12765        };
12766
12767        try {
12768            who.linkToDeath(death, 0);
12769        } catch (RemoteException e) {
12770            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12771            return;
12772        }
12773
12774        synchronized (this) {
12775            Watchdog.getInstance().setAllowRestart(allowRestart);
12776            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12777            synchronized (death) {
12778                while (who.isBinderAlive()) {
12779                    try {
12780                        death.wait();
12781                    } catch (InterruptedException e) {
12782                    }
12783                }
12784            }
12785            Watchdog.getInstance().setAllowRestart(true);
12786        }
12787    }
12788
12789    @Override
12790    public void restart() {
12791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12792                != PackageManager.PERMISSION_GRANTED) {
12793            throw new SecurityException("Requires permission "
12794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12795        }
12796
12797        Log.i(TAG, "Sending shutdown broadcast...");
12798
12799        BroadcastReceiver br = new BroadcastReceiver() {
12800            @Override public void onReceive(Context context, Intent intent) {
12801                // Now the broadcast is done, finish up the low-level shutdown.
12802                Log.i(TAG, "Shutting down activity manager...");
12803                shutdown(10000);
12804                Log.i(TAG, "Shutdown complete, restarting!");
12805                Process.killProcess(Process.myPid());
12806                System.exit(10);
12807            }
12808        };
12809
12810        // First send the high-level shut down broadcast.
12811        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12812        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12813        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12814        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12815        mContext.sendOrderedBroadcastAsUser(intent,
12816                UserHandle.ALL, null, br, mHandler, 0, null, null);
12817        */
12818        br.onReceive(mContext, intent);
12819    }
12820
12821    private long getLowRamTimeSinceIdle(long now) {
12822        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12823    }
12824
12825    @Override
12826    public void performIdleMaintenance() {
12827        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12828                != PackageManager.PERMISSION_GRANTED) {
12829            throw new SecurityException("Requires permission "
12830                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12831        }
12832
12833        synchronized (this) {
12834            final long now = SystemClock.uptimeMillis();
12835            final long timeSinceLastIdle = now - mLastIdleTime;
12836            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12837            mLastIdleTime = now;
12838            mLowRamTimeSinceLastIdle = 0;
12839            if (mLowRamStartTime != 0) {
12840                mLowRamStartTime = now;
12841            }
12842
12843            StringBuilder sb = new StringBuilder(128);
12844            sb.append("Idle maintenance over ");
12845            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12846            sb.append(" low RAM for ");
12847            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12848            Slog.i(TAG, sb.toString());
12849
12850            // If at least 1/3 of our time since the last idle period has been spent
12851            // with RAM low, then we want to kill processes.
12852            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12853
12854            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12855                ProcessRecord proc = mLruProcesses.get(i);
12856                if (proc.notCachedSinceIdle) {
12857                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12858                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12859                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12860                        if (doKilling && proc.initialIdlePss != 0
12861                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12862                            sb = new StringBuilder(128);
12863                            sb.append("Kill");
12864                            sb.append(proc.processName);
12865                            sb.append(" in idle maint: pss=");
12866                            sb.append(proc.lastPss);
12867                            sb.append(", swapPss=");
12868                            sb.append(proc.lastSwapPss);
12869                            sb.append(", initialPss=");
12870                            sb.append(proc.initialIdlePss);
12871                            sb.append(", period=");
12872                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12873                            sb.append(", lowRamPeriod=");
12874                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12875                            Slog.wtfQuiet(TAG, sb.toString());
12876                            proc.kill("idle maint (pss " + proc.lastPss
12877                                    + " from " + proc.initialIdlePss + ")", true);
12878                        }
12879                    }
12880                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12881                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12882                    proc.notCachedSinceIdle = true;
12883                    proc.initialIdlePss = 0;
12884                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12885                            mTestPssMode, isSleepingLocked(), now);
12886                }
12887            }
12888
12889            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12890            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12891        }
12892    }
12893
12894    @Override
12895    public void sendIdleJobTrigger() {
12896        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12897                != PackageManager.PERMISSION_GRANTED) {
12898            throw new SecurityException("Requires permission "
12899                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12900        }
12901
12902        final long ident = Binder.clearCallingIdentity();
12903        try {
12904            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12905                    .setPackage("android")
12906                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12907            broadcastIntent(null, intent, null, null, 0, null, null, null,
12908                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12909        } finally {
12910            Binder.restoreCallingIdentity(ident);
12911        }
12912    }
12913
12914    private void retrieveSettings() {
12915        final ContentResolver resolver = mContext.getContentResolver();
12916        final boolean freeformWindowManagement =
12917                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12918                        || Settings.Global.getInt(
12919                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12920        final boolean supportsPictureInPicture =
12921                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12922
12923        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12924        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12925        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12926        final boolean alwaysFinishActivities =
12927                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12928        final boolean lenientBackgroundCheck =
12929                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12930        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12931        final boolean forceResizable = Settings.Global.getInt(
12932                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12933        final boolean supportsLeanbackOnly =
12934                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12935
12936        // Transfer any global setting for forcing RTL layout, into a System Property
12937        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12938
12939        final Configuration configuration = new Configuration();
12940        Settings.System.getConfiguration(resolver, configuration);
12941        if (forceRtl) {
12942            // This will take care of setting the correct layout direction flags
12943            configuration.setLayoutDirection(configuration.locale);
12944        }
12945
12946        synchronized (this) {
12947            mDebugApp = mOrigDebugApp = debugApp;
12948            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12949            mAlwaysFinishActivities = alwaysFinishActivities;
12950            mLenientBackgroundCheck = lenientBackgroundCheck;
12951            mSupportsLeanbackOnly = supportsLeanbackOnly;
12952            mForceResizableActivities = forceResizable;
12953            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12954            if (supportsMultiWindow || forceResizable) {
12955                mSupportsMultiWindow = true;
12956                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12957                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12958            } else {
12959                mSupportsMultiWindow = false;
12960                mSupportsFreeformWindowManagement = false;
12961                mSupportsPictureInPicture = false;
12962            }
12963            // This happens before any activities are started, so we can
12964            // change mConfiguration in-place.
12965            updateConfigurationLocked(configuration, null, true);
12966            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12967                    "Initial config: " + mConfiguration);
12968
12969            // Load resources only after the current configuration has been set.
12970            final Resources res = mContext.getResources();
12971            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12972            mThumbnailWidth = res.getDimensionPixelSize(
12973                    com.android.internal.R.dimen.thumbnail_width);
12974            mThumbnailHeight = res.getDimensionPixelSize(
12975                    com.android.internal.R.dimen.thumbnail_height);
12976            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12977                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12978            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12979                    com.android.internal.R.string.config_appsNotReportingCrashes));
12980            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12981                mFullscreenThumbnailScale = (float) res
12982                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12983                    (float) mConfiguration.screenWidthDp;
12984            } else {
12985                mFullscreenThumbnailScale = res.getFraction(
12986                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12987            }
12988        }
12989    }
12990
12991    public boolean testIsSystemReady() {
12992        // no need to synchronize(this) just to read & return the value
12993        return mSystemReady;
12994    }
12995
12996    public void systemReady(final Runnable goingCallback) {
12997        synchronized(this) {
12998            if (mSystemReady) {
12999                // If we're done calling all the receivers, run the next "boot phase" passed in
13000                // by the SystemServer
13001                if (goingCallback != null) {
13002                    goingCallback.run();
13003                }
13004                return;
13005            }
13006
13007            mLocalDeviceIdleController
13008                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13009
13010            // Make sure we have the current profile info, since it is needed for security checks.
13011            mUserController.onSystemReady();
13012            mRecentTasks.onSystemReadyLocked();
13013            mAppOpsService.systemReady();
13014            mSystemReady = true;
13015        }
13016
13017        ArrayList<ProcessRecord> procsToKill = null;
13018        synchronized(mPidsSelfLocked) {
13019            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13020                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13021                if (!isAllowedWhileBooting(proc.info)){
13022                    if (procsToKill == null) {
13023                        procsToKill = new ArrayList<ProcessRecord>();
13024                    }
13025                    procsToKill.add(proc);
13026                }
13027            }
13028        }
13029
13030        synchronized(this) {
13031            if (procsToKill != null) {
13032                for (int i=procsToKill.size()-1; i>=0; i--) {
13033                    ProcessRecord proc = procsToKill.get(i);
13034                    Slog.i(TAG, "Removing system update proc: " + proc);
13035                    removeProcessLocked(proc, true, false, "system update done");
13036                }
13037            }
13038
13039            // Now that we have cleaned up any update processes, we
13040            // are ready to start launching real processes and know that
13041            // we won't trample on them any more.
13042            mProcessesReady = true;
13043        }
13044
13045        Slog.i(TAG, "System now ready");
13046        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13047            SystemClock.uptimeMillis());
13048
13049        synchronized(this) {
13050            // Make sure we have no pre-ready processes sitting around.
13051
13052            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13053                ResolveInfo ri = mContext.getPackageManager()
13054                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13055                                STOCK_PM_FLAGS);
13056                CharSequence errorMsg = null;
13057                if (ri != null) {
13058                    ActivityInfo ai = ri.activityInfo;
13059                    ApplicationInfo app = ai.applicationInfo;
13060                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13061                        mTopAction = Intent.ACTION_FACTORY_TEST;
13062                        mTopData = null;
13063                        mTopComponent = new ComponentName(app.packageName,
13064                                ai.name);
13065                    } else {
13066                        errorMsg = mContext.getResources().getText(
13067                                com.android.internal.R.string.factorytest_not_system);
13068                    }
13069                } else {
13070                    errorMsg = mContext.getResources().getText(
13071                            com.android.internal.R.string.factorytest_no_action);
13072                }
13073                if (errorMsg != null) {
13074                    mTopAction = null;
13075                    mTopData = null;
13076                    mTopComponent = null;
13077                    Message msg = Message.obtain();
13078                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13079                    msg.getData().putCharSequence("msg", errorMsg);
13080                    mUiHandler.sendMessage(msg);
13081                }
13082            }
13083        }
13084
13085        retrieveSettings();
13086        final int currentUserId;
13087        synchronized (this) {
13088            currentUserId = mUserController.getCurrentUserIdLocked();
13089            readGrantedUriPermissionsLocked();
13090        }
13091
13092        if (goingCallback != null) goingCallback.run();
13093
13094        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13095                Integer.toString(currentUserId), currentUserId);
13096        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13097                Integer.toString(currentUserId), currentUserId);
13098        mSystemServiceManager.startUser(currentUserId);
13099
13100        synchronized (this) {
13101            // Only start up encryption-aware persistent apps; once user is
13102            // unlocked we'll come back around and start unaware apps
13103            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13104
13105            // Start up initial activity.
13106            mBooting = true;
13107            // Enable home activity for system user, so that the system can always boot
13108            if (UserManager.isSplitSystemUser()) {
13109                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13110                try {
13111                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13112                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13113                            UserHandle.USER_SYSTEM);
13114                } catch (RemoteException e) {
13115                    throw e.rethrowAsRuntimeException();
13116                }
13117            }
13118            startHomeActivityLocked(currentUserId, "systemReady");
13119
13120            try {
13121                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13122                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13123                            + " data partition or your device will be unstable.");
13124                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13125                }
13126            } catch (RemoteException e) {
13127            }
13128
13129            if (!Build.isBuildConsistent()) {
13130                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13131                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13132            }
13133
13134            long ident = Binder.clearCallingIdentity();
13135            try {
13136                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13137                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13138                        | Intent.FLAG_RECEIVER_FOREGROUND);
13139                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13140                broadcastIntentLocked(null, null, intent,
13141                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13142                        null, false, false, MY_PID, Process.SYSTEM_UID,
13143                        currentUserId);
13144                intent = new Intent(Intent.ACTION_USER_STARTING);
13145                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13146                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13147                broadcastIntentLocked(null, null, intent,
13148                        null, new IIntentReceiver.Stub() {
13149                            @Override
13150                            public void performReceive(Intent intent, int resultCode, String data,
13151                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13152                                    throws RemoteException {
13153                            }
13154                        }, 0, null, null,
13155                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13156                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13157            } catch (Throwable t) {
13158                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13159            } finally {
13160                Binder.restoreCallingIdentity(ident);
13161            }
13162            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13163            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13164        }
13165    }
13166
13167    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13168        synchronized (this) {
13169            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13170        }
13171    }
13172
13173    void skipCurrentReceiverLocked(ProcessRecord app) {
13174        for (BroadcastQueue queue : mBroadcastQueues) {
13175            queue.skipCurrentReceiverLocked(app);
13176        }
13177    }
13178
13179    /**
13180     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13181     * The application process will exit immediately after this call returns.
13182     * @param app object of the crashing app, null for the system server
13183     * @param crashInfo describing the exception
13184     */
13185    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13186        ProcessRecord r = findAppProcess(app, "Crash");
13187        final String processName = app == null ? "system_server"
13188                : (r == null ? "unknown" : r.processName);
13189
13190        handleApplicationCrashInner("crash", r, processName, crashInfo);
13191    }
13192
13193    /* Native crash reporting uses this inner version because it needs to be somewhat
13194     * decoupled from the AM-managed cleanup lifecycle
13195     */
13196    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13197            ApplicationErrorReport.CrashInfo crashInfo) {
13198        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13199                UserHandle.getUserId(Binder.getCallingUid()), processName,
13200                r == null ? -1 : r.info.flags,
13201                crashInfo.exceptionClassName,
13202                crashInfo.exceptionMessage,
13203                crashInfo.throwFileName,
13204                crashInfo.throwLineNumber);
13205
13206        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13207
13208        mAppErrors.crashApplication(r, crashInfo);
13209    }
13210
13211    public void handleApplicationStrictModeViolation(
13212            IBinder app,
13213            int violationMask,
13214            StrictMode.ViolationInfo info) {
13215        ProcessRecord r = findAppProcess(app, "StrictMode");
13216        if (r == null) {
13217            return;
13218        }
13219
13220        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13221            Integer stackFingerprint = info.hashCode();
13222            boolean logIt = true;
13223            synchronized (mAlreadyLoggedViolatedStacks) {
13224                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13225                    logIt = false;
13226                    // TODO: sub-sample into EventLog for these, with
13227                    // the info.durationMillis?  Then we'd get
13228                    // the relative pain numbers, without logging all
13229                    // the stack traces repeatedly.  We'd want to do
13230                    // likewise in the client code, which also does
13231                    // dup suppression, before the Binder call.
13232                } else {
13233                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13234                        mAlreadyLoggedViolatedStacks.clear();
13235                    }
13236                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13237                }
13238            }
13239            if (logIt) {
13240                logStrictModeViolationToDropBox(r, info);
13241            }
13242        }
13243
13244        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13245            AppErrorResult result = new AppErrorResult();
13246            synchronized (this) {
13247                final long origId = Binder.clearCallingIdentity();
13248
13249                Message msg = Message.obtain();
13250                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13251                HashMap<String, Object> data = new HashMap<String, Object>();
13252                data.put("result", result);
13253                data.put("app", r);
13254                data.put("violationMask", violationMask);
13255                data.put("info", info);
13256                msg.obj = data;
13257                mUiHandler.sendMessage(msg);
13258
13259                Binder.restoreCallingIdentity(origId);
13260            }
13261            int res = result.get();
13262            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13263        }
13264    }
13265
13266    // Depending on the policy in effect, there could be a bunch of
13267    // these in quick succession so we try to batch these together to
13268    // minimize disk writes, number of dropbox entries, and maximize
13269    // compression, by having more fewer, larger records.
13270    private void logStrictModeViolationToDropBox(
13271            ProcessRecord process,
13272            StrictMode.ViolationInfo info) {
13273        if (info == null) {
13274            return;
13275        }
13276        final boolean isSystemApp = process == null ||
13277                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13278                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13279        final String processName = process == null ? "unknown" : process.processName;
13280        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13281        final DropBoxManager dbox = (DropBoxManager)
13282                mContext.getSystemService(Context.DROPBOX_SERVICE);
13283
13284        // Exit early if the dropbox isn't configured to accept this report type.
13285        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13286
13287        boolean bufferWasEmpty;
13288        boolean needsFlush;
13289        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13290        synchronized (sb) {
13291            bufferWasEmpty = sb.length() == 0;
13292            appendDropBoxProcessHeaders(process, processName, sb);
13293            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13294            sb.append("System-App: ").append(isSystemApp).append("\n");
13295            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13296            if (info.violationNumThisLoop != 0) {
13297                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13298            }
13299            if (info.numAnimationsRunning != 0) {
13300                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13301            }
13302            if (info.broadcastIntentAction != null) {
13303                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13304            }
13305            if (info.durationMillis != -1) {
13306                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13307            }
13308            if (info.numInstances != -1) {
13309                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13310            }
13311            if (info.tags != null) {
13312                for (String tag : info.tags) {
13313                    sb.append("Span-Tag: ").append(tag).append("\n");
13314                }
13315            }
13316            sb.append("\n");
13317            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13318                sb.append(info.crashInfo.stackTrace);
13319                sb.append("\n");
13320            }
13321            if (info.message != null) {
13322                sb.append(info.message);
13323                sb.append("\n");
13324            }
13325
13326            // Only buffer up to ~64k.  Various logging bits truncate
13327            // things at 128k.
13328            needsFlush = (sb.length() > 64 * 1024);
13329        }
13330
13331        // Flush immediately if the buffer's grown too large, or this
13332        // is a non-system app.  Non-system apps are isolated with a
13333        // different tag & policy and not batched.
13334        //
13335        // Batching is useful during internal testing with
13336        // StrictMode settings turned up high.  Without batching,
13337        // thousands of separate files could be created on boot.
13338        if (!isSystemApp || needsFlush) {
13339            new Thread("Error dump: " + dropboxTag) {
13340                @Override
13341                public void run() {
13342                    String report;
13343                    synchronized (sb) {
13344                        report = sb.toString();
13345                        sb.delete(0, sb.length());
13346                        sb.trimToSize();
13347                    }
13348                    if (report.length() != 0) {
13349                        dbox.addText(dropboxTag, report);
13350                    }
13351                }
13352            }.start();
13353            return;
13354        }
13355
13356        // System app batching:
13357        if (!bufferWasEmpty) {
13358            // An existing dropbox-writing thread is outstanding, so
13359            // we don't need to start it up.  The existing thread will
13360            // catch the buffer appends we just did.
13361            return;
13362        }
13363
13364        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13365        // (After this point, we shouldn't access AMS internal data structures.)
13366        new Thread("Error dump: " + dropboxTag) {
13367            @Override
13368            public void run() {
13369                // 5 second sleep to let stacks arrive and be batched together
13370                try {
13371                    Thread.sleep(5000);  // 5 seconds
13372                } catch (InterruptedException e) {}
13373
13374                String errorReport;
13375                synchronized (mStrictModeBuffer) {
13376                    errorReport = mStrictModeBuffer.toString();
13377                    if (errorReport.length() == 0) {
13378                        return;
13379                    }
13380                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13381                    mStrictModeBuffer.trimToSize();
13382                }
13383                dbox.addText(dropboxTag, errorReport);
13384            }
13385        }.start();
13386    }
13387
13388    /**
13389     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13390     * @param app object of the crashing app, null for the system server
13391     * @param tag reported by the caller
13392     * @param system whether this wtf is coming from the system
13393     * @param crashInfo describing the context of the error
13394     * @return true if the process should exit immediately (WTF is fatal)
13395     */
13396    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13397            final ApplicationErrorReport.CrashInfo crashInfo) {
13398        final int callingUid = Binder.getCallingUid();
13399        final int callingPid = Binder.getCallingPid();
13400
13401        if (system) {
13402            // If this is coming from the system, we could very well have low-level
13403            // system locks held, so we want to do this all asynchronously.  And we
13404            // never want this to become fatal, so there is that too.
13405            mHandler.post(new Runnable() {
13406                @Override public void run() {
13407                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13408                }
13409            });
13410            return false;
13411        }
13412
13413        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13414                crashInfo);
13415
13416        if (r != null && r.pid != Process.myPid() &&
13417                Settings.Global.getInt(mContext.getContentResolver(),
13418                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13419            mAppErrors.crashApplication(r, crashInfo);
13420            return true;
13421        } else {
13422            return false;
13423        }
13424    }
13425
13426    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13427            final ApplicationErrorReport.CrashInfo crashInfo) {
13428        final ProcessRecord r = findAppProcess(app, "WTF");
13429        final String processName = app == null ? "system_server"
13430                : (r == null ? "unknown" : r.processName);
13431
13432        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13433                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13434
13435        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13436
13437        return r;
13438    }
13439
13440    /**
13441     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13442     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13443     */
13444    private ProcessRecord findAppProcess(IBinder app, String reason) {
13445        if (app == null) {
13446            return null;
13447        }
13448
13449        synchronized (this) {
13450            final int NP = mProcessNames.getMap().size();
13451            for (int ip=0; ip<NP; ip++) {
13452                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13453                final int NA = apps.size();
13454                for (int ia=0; ia<NA; ia++) {
13455                    ProcessRecord p = apps.valueAt(ia);
13456                    if (p.thread != null && p.thread.asBinder() == app) {
13457                        return p;
13458                    }
13459                }
13460            }
13461
13462            Slog.w(TAG, "Can't find mystery application for " + reason
13463                    + " from pid=" + Binder.getCallingPid()
13464                    + " uid=" + Binder.getCallingUid() + ": " + app);
13465            return null;
13466        }
13467    }
13468
13469    /**
13470     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13471     * to append various headers to the dropbox log text.
13472     */
13473    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13474            StringBuilder sb) {
13475        // Watchdog thread ends up invoking this function (with
13476        // a null ProcessRecord) to add the stack file to dropbox.
13477        // Do not acquire a lock on this (am) in such cases, as it
13478        // could cause a potential deadlock, if and when watchdog
13479        // is invoked due to unavailability of lock on am and it
13480        // would prevent watchdog from killing system_server.
13481        if (process == null) {
13482            sb.append("Process: ").append(processName).append("\n");
13483            return;
13484        }
13485        // Note: ProcessRecord 'process' is guarded by the service
13486        // instance.  (notably process.pkgList, which could otherwise change
13487        // concurrently during execution of this method)
13488        synchronized (this) {
13489            sb.append("Process: ").append(processName).append("\n");
13490            int flags = process.info.flags;
13491            IPackageManager pm = AppGlobals.getPackageManager();
13492            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13493            for (int ip=0; ip<process.pkgList.size(); ip++) {
13494                String pkg = process.pkgList.keyAt(ip);
13495                sb.append("Package: ").append(pkg);
13496                try {
13497                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13498                    if (pi != null) {
13499                        sb.append(" v").append(pi.versionCode);
13500                        if (pi.versionName != null) {
13501                            sb.append(" (").append(pi.versionName).append(")");
13502                        }
13503                    }
13504                } catch (RemoteException e) {
13505                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13506                }
13507                sb.append("\n");
13508            }
13509        }
13510    }
13511
13512    private static String processClass(ProcessRecord process) {
13513        if (process == null || process.pid == MY_PID) {
13514            return "system_server";
13515        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13516            return "system_app";
13517        } else {
13518            return "data_app";
13519        }
13520    }
13521
13522    private volatile long mWtfClusterStart;
13523    private volatile int mWtfClusterCount;
13524
13525    /**
13526     * Write a description of an error (crash, WTF, ANR) to the drop box.
13527     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13528     * @param process which caused the error, null means the system server
13529     * @param activity which triggered the error, null if unknown
13530     * @param parent activity related to the error, null if unknown
13531     * @param subject line related to the error, null if absent
13532     * @param report in long form describing the error, null if absent
13533     * @param logFile to include in the report, null if none
13534     * @param crashInfo giving an application stack trace, null if absent
13535     */
13536    public void addErrorToDropBox(String eventType,
13537            ProcessRecord process, String processName, ActivityRecord activity,
13538            ActivityRecord parent, String subject,
13539            final String report, final File logFile,
13540            final ApplicationErrorReport.CrashInfo crashInfo) {
13541        // NOTE -- this must never acquire the ActivityManagerService lock,
13542        // otherwise the watchdog may be prevented from resetting the system.
13543
13544        final String dropboxTag = processClass(process) + "_" + eventType;
13545        final DropBoxManager dbox = (DropBoxManager)
13546                mContext.getSystemService(Context.DROPBOX_SERVICE);
13547
13548        // Exit early if the dropbox isn't configured to accept this report type.
13549        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13550
13551        // Rate-limit how often we're willing to do the heavy lifting below to
13552        // collect and record logs; currently 5 logs per 10 second period.
13553        final long now = SystemClock.elapsedRealtime();
13554        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13555            mWtfClusterStart = now;
13556            mWtfClusterCount = 1;
13557        } else {
13558            if (mWtfClusterCount++ >= 5) return;
13559        }
13560
13561        final StringBuilder sb = new StringBuilder(1024);
13562        appendDropBoxProcessHeaders(process, processName, sb);
13563        if (process != null) {
13564            sb.append("Foreground: ")
13565                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13566                    .append("\n");
13567        }
13568        if (activity != null) {
13569            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13570        }
13571        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13572            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13573        }
13574        if (parent != null && parent != activity) {
13575            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13576        }
13577        if (subject != null) {
13578            sb.append("Subject: ").append(subject).append("\n");
13579        }
13580        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13581        if (Debug.isDebuggerConnected()) {
13582            sb.append("Debugger: Connected\n");
13583        }
13584        sb.append("\n");
13585
13586        // Do the rest in a worker thread to avoid blocking the caller on I/O
13587        // (After this point, we shouldn't access AMS internal data structures.)
13588        Thread worker = new Thread("Error dump: " + dropboxTag) {
13589            @Override
13590            public void run() {
13591                if (report != null) {
13592                    sb.append(report);
13593                }
13594                if (logFile != null) {
13595                    try {
13596                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13597                                    "\n\n[[TRUNCATED]]"));
13598                    } catch (IOException e) {
13599                        Slog.e(TAG, "Error reading " + logFile, e);
13600                    }
13601                }
13602                if (crashInfo != null && crashInfo.stackTrace != null) {
13603                    sb.append(crashInfo.stackTrace);
13604                }
13605
13606                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13607                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13608                if (lines > 0) {
13609                    sb.append("\n");
13610
13611                    // Merge several logcat streams, and take the last N lines
13612                    InputStreamReader input = null;
13613                    try {
13614                        java.lang.Process logcat = new ProcessBuilder(
13615                                "/system/bin/timeout", "-k", "15s", "10s",
13616                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13617                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13618                                        .redirectErrorStream(true).start();
13619
13620                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13621                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13622                        input = new InputStreamReader(logcat.getInputStream());
13623
13624                        int num;
13625                        char[] buf = new char[8192];
13626                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13627                    } catch (IOException e) {
13628                        Slog.e(TAG, "Error running logcat", e);
13629                    } finally {
13630                        if (input != null) try { input.close(); } catch (IOException e) {}
13631                    }
13632                }
13633
13634                dbox.addText(dropboxTag, sb.toString());
13635            }
13636        };
13637
13638        if (process == null) {
13639            // If process is null, we are being called from some internal code
13640            // and may be about to die -- run this synchronously.
13641            worker.run();
13642        } else {
13643            worker.start();
13644        }
13645    }
13646
13647    @Override
13648    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13649        enforceNotIsolatedCaller("getProcessesInErrorState");
13650        // assume our apps are happy - lazy create the list
13651        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13652
13653        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13654                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13655        int userId = UserHandle.getUserId(Binder.getCallingUid());
13656
13657        synchronized (this) {
13658
13659            // iterate across all processes
13660            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13661                ProcessRecord app = mLruProcesses.get(i);
13662                if (!allUsers && app.userId != userId) {
13663                    continue;
13664                }
13665                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13666                    // This one's in trouble, so we'll generate a report for it
13667                    // crashes are higher priority (in case there's a crash *and* an anr)
13668                    ActivityManager.ProcessErrorStateInfo report = null;
13669                    if (app.crashing) {
13670                        report = app.crashingReport;
13671                    } else if (app.notResponding) {
13672                        report = app.notRespondingReport;
13673                    }
13674
13675                    if (report != null) {
13676                        if (errList == null) {
13677                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13678                        }
13679                        errList.add(report);
13680                    } else {
13681                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13682                                " crashing = " + app.crashing +
13683                                " notResponding = " + app.notResponding);
13684                    }
13685                }
13686            }
13687        }
13688
13689        return errList;
13690    }
13691
13692    static int procStateToImportance(int procState, int memAdj,
13693            ActivityManager.RunningAppProcessInfo currApp) {
13694        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13695        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13696            currApp.lru = memAdj;
13697        } else {
13698            currApp.lru = 0;
13699        }
13700        return imp;
13701    }
13702
13703    private void fillInProcMemInfo(ProcessRecord app,
13704            ActivityManager.RunningAppProcessInfo outInfo) {
13705        outInfo.pid = app.pid;
13706        outInfo.uid = app.info.uid;
13707        if (mHeavyWeightProcess == app) {
13708            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13709        }
13710        if (app.persistent) {
13711            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13712        }
13713        if (app.activities.size() > 0) {
13714            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13715        }
13716        outInfo.lastTrimLevel = app.trimMemoryLevel;
13717        int adj = app.curAdj;
13718        int procState = app.curProcState;
13719        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13720        outInfo.importanceReasonCode = app.adjTypeCode;
13721        outInfo.processState = app.curProcState;
13722    }
13723
13724    @Override
13725    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13726        enforceNotIsolatedCaller("getRunningAppProcesses");
13727
13728        final int callingUid = Binder.getCallingUid();
13729
13730        // Lazy instantiation of list
13731        List<ActivityManager.RunningAppProcessInfo> runList = null;
13732        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13733                callingUid) == PackageManager.PERMISSION_GRANTED;
13734        final int userId = UserHandle.getUserId(callingUid);
13735        final boolean allUids = isGetTasksAllowed(
13736                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13737
13738        synchronized (this) {
13739            // Iterate across all processes
13740            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13741                ProcessRecord app = mLruProcesses.get(i);
13742                if ((!allUsers && app.userId != userId)
13743                        || (!allUids && app.uid != callingUid)) {
13744                    continue;
13745                }
13746                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13747                    // Generate process state info for running application
13748                    ActivityManager.RunningAppProcessInfo currApp =
13749                        new ActivityManager.RunningAppProcessInfo(app.processName,
13750                                app.pid, app.getPackageList());
13751                    fillInProcMemInfo(app, currApp);
13752                    if (app.adjSource instanceof ProcessRecord) {
13753                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13754                        currApp.importanceReasonImportance =
13755                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13756                                        app.adjSourceProcState);
13757                    } else if (app.adjSource instanceof ActivityRecord) {
13758                        ActivityRecord r = (ActivityRecord)app.adjSource;
13759                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13760                    }
13761                    if (app.adjTarget instanceof ComponentName) {
13762                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13763                    }
13764                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13765                    //        + " lru=" + currApp.lru);
13766                    if (runList == null) {
13767                        runList = new ArrayList<>();
13768                    }
13769                    runList.add(currApp);
13770                }
13771            }
13772        }
13773        return runList;
13774    }
13775
13776    @Override
13777    public List<ApplicationInfo> getRunningExternalApplications() {
13778        enforceNotIsolatedCaller("getRunningExternalApplications");
13779        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13780        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13781        if (runningApps != null && runningApps.size() > 0) {
13782            Set<String> extList = new HashSet<String>();
13783            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13784                if (app.pkgList != null) {
13785                    for (String pkg : app.pkgList) {
13786                        extList.add(pkg);
13787                    }
13788                }
13789            }
13790            IPackageManager pm = AppGlobals.getPackageManager();
13791            for (String pkg : extList) {
13792                try {
13793                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13794                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13795                        retList.add(info);
13796                    }
13797                } catch (RemoteException e) {
13798                }
13799            }
13800        }
13801        return retList;
13802    }
13803
13804    @Override
13805    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13806        enforceNotIsolatedCaller("getMyMemoryState");
13807        synchronized (this) {
13808            ProcessRecord proc;
13809            synchronized (mPidsSelfLocked) {
13810                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13811            }
13812            fillInProcMemInfo(proc, outInfo);
13813        }
13814    }
13815
13816    @Override
13817    public int getMemoryTrimLevel() {
13818        enforceNotIsolatedCaller("getMyMemoryState");
13819        synchronized (this) {
13820            return mLastMemoryLevel;
13821        }
13822    }
13823
13824    @Override
13825    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13826            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13827        (new ActivityManagerShellCommand(this, false)).exec(
13828                this, in, out, err, args, resultReceiver);
13829    }
13830
13831    @Override
13832    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13833        if (checkCallingPermission(android.Manifest.permission.DUMP)
13834                != PackageManager.PERMISSION_GRANTED) {
13835            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13836                    + Binder.getCallingPid()
13837                    + ", uid=" + Binder.getCallingUid()
13838                    + " without permission "
13839                    + android.Manifest.permission.DUMP);
13840            return;
13841        }
13842
13843        boolean dumpAll = false;
13844        boolean dumpClient = false;
13845        boolean dumpCheckin = false;
13846        boolean dumpCheckinFormat = false;
13847        String dumpPackage = null;
13848
13849        int opti = 0;
13850        while (opti < args.length) {
13851            String opt = args[opti];
13852            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13853                break;
13854            }
13855            opti++;
13856            if ("-a".equals(opt)) {
13857                dumpAll = true;
13858            } else if ("-c".equals(opt)) {
13859                dumpClient = true;
13860            } else if ("-p".equals(opt)) {
13861                if (opti < args.length) {
13862                    dumpPackage = args[opti];
13863                    opti++;
13864                } else {
13865                    pw.println("Error: -p option requires package argument");
13866                    return;
13867                }
13868                dumpClient = true;
13869            } else if ("--checkin".equals(opt)) {
13870                dumpCheckin = dumpCheckinFormat = true;
13871            } else if ("-C".equals(opt)) {
13872                dumpCheckinFormat = true;
13873            } else if ("-h".equals(opt)) {
13874                ActivityManagerShellCommand.dumpHelp(pw, true);
13875                return;
13876            } else {
13877                pw.println("Unknown argument: " + opt + "; use -h for help");
13878            }
13879        }
13880
13881        long origId = Binder.clearCallingIdentity();
13882        boolean more = false;
13883        // Is the caller requesting to dump a particular piece of data?
13884        if (opti < args.length) {
13885            String cmd = args[opti];
13886            opti++;
13887            if ("activities".equals(cmd) || "a".equals(cmd)) {
13888                synchronized (this) {
13889                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13890                }
13891            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13892                synchronized (this) {
13893                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13894                }
13895            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13896                String[] newArgs;
13897                String name;
13898                if (opti >= args.length) {
13899                    name = null;
13900                    newArgs = EMPTY_STRING_ARRAY;
13901                } else {
13902                    dumpPackage = args[opti];
13903                    opti++;
13904                    newArgs = new String[args.length - opti];
13905                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13906                            args.length - opti);
13907                }
13908                synchronized (this) {
13909                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13910                }
13911            } else if ("broadcast-stats".equals(cmd)) {
13912                String[] newArgs;
13913                String name;
13914                if (opti >= args.length) {
13915                    name = null;
13916                    newArgs = EMPTY_STRING_ARRAY;
13917                } else {
13918                    dumpPackage = args[opti];
13919                    opti++;
13920                    newArgs = new String[args.length - opti];
13921                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13922                            args.length - opti);
13923                }
13924                synchronized (this) {
13925                    if (dumpCheckinFormat) {
13926                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13927                                dumpPackage);
13928                    } else {
13929                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13930                    }
13931                }
13932            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13933                String[] newArgs;
13934                String name;
13935                if (opti >= args.length) {
13936                    name = null;
13937                    newArgs = EMPTY_STRING_ARRAY;
13938                } else {
13939                    dumpPackage = args[opti];
13940                    opti++;
13941                    newArgs = new String[args.length - opti];
13942                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13943                            args.length - opti);
13944                }
13945                synchronized (this) {
13946                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13947                }
13948            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13949                String[] newArgs;
13950                String name;
13951                if (opti >= args.length) {
13952                    name = null;
13953                    newArgs = EMPTY_STRING_ARRAY;
13954                } else {
13955                    dumpPackage = args[opti];
13956                    opti++;
13957                    newArgs = new String[args.length - opti];
13958                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13959                            args.length - opti);
13960                }
13961                synchronized (this) {
13962                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13963                }
13964            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13965                synchronized (this) {
13966                    dumpOomLocked(fd, pw, args, opti, true);
13967                }
13968            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13969                synchronized (this) {
13970                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13971                }
13972            } else if ("provider".equals(cmd)) {
13973                String[] newArgs;
13974                String name;
13975                if (opti >= args.length) {
13976                    name = null;
13977                    newArgs = EMPTY_STRING_ARRAY;
13978                } else {
13979                    name = args[opti];
13980                    opti++;
13981                    newArgs = new String[args.length - opti];
13982                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13983                }
13984                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13985                    pw.println("No providers match: " + name);
13986                    pw.println("Use -h for help.");
13987                }
13988            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13989                synchronized (this) {
13990                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13991                }
13992            } else if ("service".equals(cmd)) {
13993                String[] newArgs;
13994                String name;
13995                if (opti >= args.length) {
13996                    name = null;
13997                    newArgs = EMPTY_STRING_ARRAY;
13998                } else {
13999                    name = args[opti];
14000                    opti++;
14001                    newArgs = new String[args.length - opti];
14002                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14003                            args.length - opti);
14004                }
14005                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14006                    pw.println("No services match: " + name);
14007                    pw.println("Use -h for help.");
14008                }
14009            } else if ("package".equals(cmd)) {
14010                String[] newArgs;
14011                if (opti >= args.length) {
14012                    pw.println("package: no package name specified");
14013                    pw.println("Use -h for help.");
14014                } else {
14015                    dumpPackage = args[opti];
14016                    opti++;
14017                    newArgs = new String[args.length - opti];
14018                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14019                            args.length - opti);
14020                    args = newArgs;
14021                    opti = 0;
14022                    more = true;
14023                }
14024            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14025                synchronized (this) {
14026                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14027                }
14028            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14029                if (dumpClient) {
14030                    ActiveServices.ServiceDumper dumper;
14031                    synchronized (this) {
14032                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14033                                dumpPackage);
14034                    }
14035                    dumper.dumpWithClient();
14036                } else {
14037                    synchronized (this) {
14038                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14039                                dumpPackage).dumpLocked();
14040                    }
14041                }
14042            } else if ("locks".equals(cmd)) {
14043                LockGuard.dump(fd, pw, args);
14044            } else {
14045                // Dumping a single activity?
14046                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14047                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14048                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14049                    if (res < 0) {
14050                        pw.println("Bad activity command, or no activities match: " + cmd);
14051                        pw.println("Use -h for help.");
14052                    }
14053                }
14054            }
14055            if (!more) {
14056                Binder.restoreCallingIdentity(origId);
14057                return;
14058            }
14059        }
14060
14061        // No piece of data specified, dump everything.
14062        if (dumpCheckinFormat) {
14063            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14064        } else if (dumpClient) {
14065            ActiveServices.ServiceDumper sdumper;
14066            synchronized (this) {
14067                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14068                pw.println();
14069                if (dumpAll) {
14070                    pw.println("-------------------------------------------------------------------------------");
14071                }
14072                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14073                pw.println();
14074                if (dumpAll) {
14075                    pw.println("-------------------------------------------------------------------------------");
14076                }
14077                if (dumpAll || dumpPackage != null) {
14078                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14079                    pw.println();
14080                    if (dumpAll) {
14081                        pw.println("-------------------------------------------------------------------------------");
14082                    }
14083                }
14084                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14085                pw.println();
14086                if (dumpAll) {
14087                    pw.println("-------------------------------------------------------------------------------");
14088                }
14089                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14090                pw.println();
14091                if (dumpAll) {
14092                    pw.println("-------------------------------------------------------------------------------");
14093                }
14094                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14095                        dumpPackage);
14096            }
14097            sdumper.dumpWithClient();
14098            pw.println();
14099            synchronized (this) {
14100                if (dumpAll) {
14101                    pw.println("-------------------------------------------------------------------------------");
14102                }
14103                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14104                pw.println();
14105                if (dumpAll) {
14106                    pw.println("-------------------------------------------------------------------------------");
14107                }
14108                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14109                if (mAssociations.size() > 0) {
14110                    pw.println();
14111                    if (dumpAll) {
14112                        pw.println("-------------------------------------------------------------------------------");
14113                    }
14114                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14115                }
14116                pw.println();
14117                if (dumpAll) {
14118                    pw.println("-------------------------------------------------------------------------------");
14119                }
14120                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14121            }
14122
14123        } else {
14124            synchronized (this) {
14125                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14126                pw.println();
14127                if (dumpAll) {
14128                    pw.println("-------------------------------------------------------------------------------");
14129                }
14130                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14131                pw.println();
14132                if (dumpAll) {
14133                    pw.println("-------------------------------------------------------------------------------");
14134                }
14135                if (dumpAll || dumpPackage != null) {
14136                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14137                    pw.println();
14138                    if (dumpAll) {
14139                        pw.println("-------------------------------------------------------------------------------");
14140                    }
14141                }
14142                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14143                pw.println();
14144                if (dumpAll) {
14145                    pw.println("-------------------------------------------------------------------------------");
14146                }
14147                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14148                pw.println();
14149                if (dumpAll) {
14150                    pw.println("-------------------------------------------------------------------------------");
14151                }
14152                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14153                        .dumpLocked();
14154                pw.println();
14155                if (dumpAll) {
14156                    pw.println("-------------------------------------------------------------------------------");
14157                }
14158                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14159                pw.println();
14160                if (dumpAll) {
14161                    pw.println("-------------------------------------------------------------------------------");
14162                }
14163                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14164                if (mAssociations.size() > 0) {
14165                    pw.println();
14166                    if (dumpAll) {
14167                        pw.println("-------------------------------------------------------------------------------");
14168                    }
14169                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14170                }
14171                pw.println();
14172                if (dumpAll) {
14173                    pw.println("-------------------------------------------------------------------------------");
14174                }
14175                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14176            }
14177        }
14178        Binder.restoreCallingIdentity(origId);
14179    }
14180
14181    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14182            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14183        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14184
14185        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14186                dumpPackage);
14187        boolean needSep = printedAnything;
14188
14189        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14190                dumpPackage, needSep, "  mFocusedActivity: ");
14191        if (printed) {
14192            printedAnything = true;
14193            needSep = false;
14194        }
14195
14196        if (dumpPackage == null) {
14197            if (needSep) {
14198                pw.println();
14199            }
14200            needSep = true;
14201            printedAnything = true;
14202            mStackSupervisor.dump(pw, "  ");
14203        }
14204
14205        if (!printedAnything) {
14206            pw.println("  (nothing)");
14207        }
14208    }
14209
14210    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14211            int opti, boolean dumpAll, String dumpPackage) {
14212        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14213
14214        boolean printedAnything = false;
14215
14216        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14217            boolean printedHeader = false;
14218
14219            final int N = mRecentTasks.size();
14220            for (int i=0; i<N; i++) {
14221                TaskRecord tr = mRecentTasks.get(i);
14222                if (dumpPackage != null) {
14223                    if (tr.realActivity == null ||
14224                            !dumpPackage.equals(tr.realActivity)) {
14225                        continue;
14226                    }
14227                }
14228                if (!printedHeader) {
14229                    pw.println("  Recent tasks:");
14230                    printedHeader = true;
14231                    printedAnything = true;
14232                }
14233                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14234                        pw.println(tr);
14235                if (dumpAll) {
14236                    mRecentTasks.get(i).dump(pw, "    ");
14237                }
14238            }
14239        }
14240
14241        if (!printedAnything) {
14242            pw.println("  (nothing)");
14243        }
14244    }
14245
14246    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14247            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14248        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14249
14250        int dumpUid = 0;
14251        if (dumpPackage != null) {
14252            IPackageManager pm = AppGlobals.getPackageManager();
14253            try {
14254                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14255            } catch (RemoteException e) {
14256            }
14257        }
14258
14259        boolean printedAnything = false;
14260
14261        final long now = SystemClock.uptimeMillis();
14262
14263        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14264            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14265                    = mAssociations.valueAt(i1);
14266            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14267                SparseArray<ArrayMap<String, Association>> sourceUids
14268                        = targetComponents.valueAt(i2);
14269                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14270                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14271                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14272                        Association ass = sourceProcesses.valueAt(i4);
14273                        if (dumpPackage != null) {
14274                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14275                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14276                                continue;
14277                            }
14278                        }
14279                        printedAnything = true;
14280                        pw.print("  ");
14281                        pw.print(ass.mTargetProcess);
14282                        pw.print("/");
14283                        UserHandle.formatUid(pw, ass.mTargetUid);
14284                        pw.print(" <- ");
14285                        pw.print(ass.mSourceProcess);
14286                        pw.print("/");
14287                        UserHandle.formatUid(pw, ass.mSourceUid);
14288                        pw.println();
14289                        pw.print("    via ");
14290                        pw.print(ass.mTargetComponent.flattenToShortString());
14291                        pw.println();
14292                        pw.print("    ");
14293                        long dur = ass.mTime;
14294                        if (ass.mNesting > 0) {
14295                            dur += now - ass.mStartTime;
14296                        }
14297                        TimeUtils.formatDuration(dur, pw);
14298                        pw.print(" (");
14299                        pw.print(ass.mCount);
14300                        pw.print(" times)");
14301                        pw.print("  ");
14302                        for (int i=0; i<ass.mStateTimes.length; i++) {
14303                            long amt = ass.mStateTimes[i];
14304                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14305                                amt += now - ass.mLastStateUptime;
14306                            }
14307                            if (amt != 0) {
14308                                pw.print(" ");
14309                                pw.print(ProcessList.makeProcStateString(
14310                                            i + ActivityManager.MIN_PROCESS_STATE));
14311                                pw.print("=");
14312                                TimeUtils.formatDuration(amt, pw);
14313                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14314                                    pw.print("*");
14315                                }
14316                            }
14317                        }
14318                        pw.println();
14319                        if (ass.mNesting > 0) {
14320                            pw.print("    Currently active: ");
14321                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14322                            pw.println();
14323                        }
14324                    }
14325                }
14326            }
14327
14328        }
14329
14330        if (!printedAnything) {
14331            pw.println("  (nothing)");
14332        }
14333    }
14334
14335    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14336            String header, boolean needSep) {
14337        boolean printed = false;
14338        int whichAppId = -1;
14339        if (dumpPackage != null) {
14340            try {
14341                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14342                        dumpPackage, 0);
14343                whichAppId = UserHandle.getAppId(info.uid);
14344            } catch (NameNotFoundException e) {
14345                e.printStackTrace();
14346            }
14347        }
14348        for (int i=0; i<uids.size(); i++) {
14349            UidRecord uidRec = uids.valueAt(i);
14350            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14351                continue;
14352            }
14353            if (!printed) {
14354                printed = true;
14355                if (needSep) {
14356                    pw.println();
14357                }
14358                pw.print("  ");
14359                pw.println(header);
14360                needSep = true;
14361            }
14362            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14363            pw.print(": "); pw.println(uidRec);
14364        }
14365        return printed;
14366    }
14367
14368    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14369            int opti, boolean dumpAll, String dumpPackage) {
14370        boolean needSep = false;
14371        boolean printedAnything = false;
14372        int numPers = 0;
14373
14374        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14375
14376        if (dumpAll) {
14377            final int NP = mProcessNames.getMap().size();
14378            for (int ip=0; ip<NP; ip++) {
14379                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14380                final int NA = procs.size();
14381                for (int ia=0; ia<NA; ia++) {
14382                    ProcessRecord r = procs.valueAt(ia);
14383                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14384                        continue;
14385                    }
14386                    if (!needSep) {
14387                        pw.println("  All known processes:");
14388                        needSep = true;
14389                        printedAnything = true;
14390                    }
14391                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14392                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14393                        pw.print(" "); pw.println(r);
14394                    r.dump(pw, "    ");
14395                    if (r.persistent) {
14396                        numPers++;
14397                    }
14398                }
14399            }
14400        }
14401
14402        if (mIsolatedProcesses.size() > 0) {
14403            boolean printed = false;
14404            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14405                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14406                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14407                    continue;
14408                }
14409                if (!printed) {
14410                    if (needSep) {
14411                        pw.println();
14412                    }
14413                    pw.println("  Isolated process list (sorted by uid):");
14414                    printedAnything = true;
14415                    printed = true;
14416                    needSep = true;
14417                }
14418                pw.println(String.format("%sIsolated #%2d: %s",
14419                        "    ", i, r.toString()));
14420            }
14421        }
14422
14423        if (mActiveUids.size() > 0) {
14424            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14425                printedAnything = needSep = true;
14426            }
14427        }
14428        if (mValidateUids.size() > 0) {
14429            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14430                printedAnything = needSep = true;
14431            }
14432        }
14433
14434        if (mLruProcesses.size() > 0) {
14435            if (needSep) {
14436                pw.println();
14437            }
14438            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14439                    pw.print(" total, non-act at ");
14440                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14441                    pw.print(", non-svc at ");
14442                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14443                    pw.println("):");
14444            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14445            needSep = true;
14446            printedAnything = true;
14447        }
14448
14449        if (dumpAll || dumpPackage != null) {
14450            synchronized (mPidsSelfLocked) {
14451                boolean printed = false;
14452                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14453                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14454                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14455                        continue;
14456                    }
14457                    if (!printed) {
14458                        if (needSep) pw.println();
14459                        needSep = true;
14460                        pw.println("  PID mappings:");
14461                        printed = true;
14462                        printedAnything = true;
14463                    }
14464                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14465                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14466                }
14467            }
14468        }
14469
14470        if (mForegroundProcesses.size() > 0) {
14471            synchronized (mPidsSelfLocked) {
14472                boolean printed = false;
14473                for (int i=0; i<mForegroundProcesses.size(); i++) {
14474                    ProcessRecord r = mPidsSelfLocked.get(
14475                            mForegroundProcesses.valueAt(i).pid);
14476                    if (dumpPackage != null && (r == null
14477                            || !r.pkgList.containsKey(dumpPackage))) {
14478                        continue;
14479                    }
14480                    if (!printed) {
14481                        if (needSep) pw.println();
14482                        needSep = true;
14483                        pw.println("  Foreground Processes:");
14484                        printed = true;
14485                        printedAnything = true;
14486                    }
14487                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14488                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14489                }
14490            }
14491        }
14492
14493        if (mPersistentStartingProcesses.size() > 0) {
14494            if (needSep) pw.println();
14495            needSep = true;
14496            printedAnything = true;
14497            pw.println("  Persisent processes that are starting:");
14498            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14499                    "Starting Norm", "Restarting PERS", dumpPackage);
14500        }
14501
14502        if (mRemovedProcesses.size() > 0) {
14503            if (needSep) pw.println();
14504            needSep = true;
14505            printedAnything = true;
14506            pw.println("  Processes that are being removed:");
14507            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14508                    "Removed Norm", "Removed PERS", dumpPackage);
14509        }
14510
14511        if (mProcessesOnHold.size() > 0) {
14512            if (needSep) pw.println();
14513            needSep = true;
14514            printedAnything = true;
14515            pw.println("  Processes that are on old until the system is ready:");
14516            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14517                    "OnHold Norm", "OnHold PERS", dumpPackage);
14518        }
14519
14520        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14521
14522        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14523        if (needSep) {
14524            printedAnything = true;
14525        }
14526
14527        if (dumpPackage == null) {
14528            pw.println();
14529            needSep = false;
14530            mUserController.dump(pw, dumpAll);
14531        }
14532        if (mHomeProcess != null && (dumpPackage == null
14533                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14534            if (needSep) {
14535                pw.println();
14536                needSep = false;
14537            }
14538            pw.println("  mHomeProcess: " + mHomeProcess);
14539        }
14540        if (mPreviousProcess != null && (dumpPackage == null
14541                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14542            if (needSep) {
14543                pw.println();
14544                needSep = false;
14545            }
14546            pw.println("  mPreviousProcess: " + mPreviousProcess);
14547        }
14548        if (dumpAll) {
14549            StringBuilder sb = new StringBuilder(128);
14550            sb.append("  mPreviousProcessVisibleTime: ");
14551            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14552            pw.println(sb);
14553        }
14554        if (mHeavyWeightProcess != null && (dumpPackage == null
14555                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14556            if (needSep) {
14557                pw.println();
14558                needSep = false;
14559            }
14560            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14561        }
14562        if (dumpPackage == null) {
14563            pw.println("  mConfiguration: " + mConfiguration);
14564        }
14565        if (dumpAll) {
14566            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14567            if (mCompatModePackages.getPackages().size() > 0) {
14568                boolean printed = false;
14569                for (Map.Entry<String, Integer> entry
14570                        : mCompatModePackages.getPackages().entrySet()) {
14571                    String pkg = entry.getKey();
14572                    int mode = entry.getValue();
14573                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14574                        continue;
14575                    }
14576                    if (!printed) {
14577                        pw.println("  mScreenCompatPackages:");
14578                        printed = true;
14579                    }
14580                    pw.print("    "); pw.print(pkg); pw.print(": ");
14581                            pw.print(mode); pw.println();
14582                }
14583            }
14584        }
14585        if (dumpPackage == null) {
14586            pw.println("  mWakefulness="
14587                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14588            pw.println("  mSleepTokens=" + mSleepTokens);
14589            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14590                    + lockScreenShownToString());
14591            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14592            if (mRunningVoice != null) {
14593                pw.println("  mRunningVoice=" + mRunningVoice);
14594                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14595            }
14596        }
14597        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14598                || mOrigWaitForDebugger) {
14599            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14600                    || dumpPackage.equals(mOrigDebugApp)) {
14601                if (needSep) {
14602                    pw.println();
14603                    needSep = false;
14604                }
14605                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14606                        + " mDebugTransient=" + mDebugTransient
14607                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14608            }
14609        }
14610        if (mCurAppTimeTracker != null) {
14611            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14612        }
14613        if (mMemWatchProcesses.getMap().size() > 0) {
14614            pw.println("  Mem watch processes:");
14615            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14616                    = mMemWatchProcesses.getMap();
14617            for (int i=0; i<procs.size(); i++) {
14618                final String proc = procs.keyAt(i);
14619                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14620                for (int j=0; j<uids.size(); j++) {
14621                    if (needSep) {
14622                        pw.println();
14623                        needSep = false;
14624                    }
14625                    StringBuilder sb = new StringBuilder();
14626                    sb.append("    ").append(proc).append('/');
14627                    UserHandle.formatUid(sb, uids.keyAt(j));
14628                    Pair<Long, String> val = uids.valueAt(j);
14629                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14630                    if (val.second != null) {
14631                        sb.append(", report to ").append(val.second);
14632                    }
14633                    pw.println(sb.toString());
14634                }
14635            }
14636            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14637            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14638            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14639                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14640        }
14641        if (mTrackAllocationApp != null) {
14642            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14643                if (needSep) {
14644                    pw.println();
14645                    needSep = false;
14646                }
14647                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14648            }
14649        }
14650        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14651                || mProfileFd != null) {
14652            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14653                if (needSep) {
14654                    pw.println();
14655                    needSep = false;
14656                }
14657                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14658                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14659                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14660                        + mAutoStopProfiler);
14661                pw.println("  mProfileType=" + mProfileType);
14662            }
14663        }
14664        if (mNativeDebuggingApp != null) {
14665            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14666                if (needSep) {
14667                    pw.println();
14668                    needSep = false;
14669                }
14670                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14671            }
14672        }
14673        if (dumpPackage == null) {
14674            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14675                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14676                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14677            }
14678            if (mController != null) {
14679                pw.println("  mController=" + mController
14680                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14681            }
14682            if (dumpAll) {
14683                pw.println("  Total persistent processes: " + numPers);
14684                pw.println("  mProcessesReady=" + mProcessesReady
14685                        + " mSystemReady=" + mSystemReady
14686                        + " mBooted=" + mBooted
14687                        + " mFactoryTest=" + mFactoryTest);
14688                pw.println("  mBooting=" + mBooting
14689                        + " mCallFinishBooting=" + mCallFinishBooting
14690                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14691                pw.print("  mLastPowerCheckRealtime=");
14692                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14693                        pw.println("");
14694                pw.print("  mLastPowerCheckUptime=");
14695                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14696                        pw.println("");
14697                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14698                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14699                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14700                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14701                        + " (" + mLruProcesses.size() + " total)"
14702                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14703                        + " mNumServiceProcs=" + mNumServiceProcs
14704                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14705                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14706                        + " mLastMemoryLevel=" + mLastMemoryLevel
14707                        + " mLastNumProcesses=" + mLastNumProcesses);
14708                long now = SystemClock.uptimeMillis();
14709                pw.print("  mLastIdleTime=");
14710                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14711                        pw.print(" mLowRamSinceLastIdle=");
14712                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14713                        pw.println();
14714            }
14715        }
14716
14717        if (!printedAnything) {
14718            pw.println("  (nothing)");
14719        }
14720    }
14721
14722    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14723            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14724        if (mProcessesToGc.size() > 0) {
14725            boolean printed = false;
14726            long now = SystemClock.uptimeMillis();
14727            for (int i=0; i<mProcessesToGc.size(); i++) {
14728                ProcessRecord proc = mProcessesToGc.get(i);
14729                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14730                    continue;
14731                }
14732                if (!printed) {
14733                    if (needSep) pw.println();
14734                    needSep = true;
14735                    pw.println("  Processes that are waiting to GC:");
14736                    printed = true;
14737                }
14738                pw.print("    Process "); pw.println(proc);
14739                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14740                        pw.print(", last gced=");
14741                        pw.print(now-proc.lastRequestedGc);
14742                        pw.print(" ms ago, last lowMem=");
14743                        pw.print(now-proc.lastLowMemory);
14744                        pw.println(" ms ago");
14745
14746            }
14747        }
14748        return needSep;
14749    }
14750
14751    void printOomLevel(PrintWriter pw, String name, int adj) {
14752        pw.print("    ");
14753        if (adj >= 0) {
14754            pw.print(' ');
14755            if (adj < 10) pw.print(' ');
14756        } else {
14757            if (adj > -10) pw.print(' ');
14758        }
14759        pw.print(adj);
14760        pw.print(": ");
14761        pw.print(name);
14762        pw.print(" (");
14763        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14764        pw.println(")");
14765    }
14766
14767    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14768            int opti, boolean dumpAll) {
14769        boolean needSep = false;
14770
14771        if (mLruProcesses.size() > 0) {
14772            if (needSep) pw.println();
14773            needSep = true;
14774            pw.println("  OOM levels:");
14775            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14776            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14777            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14778            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14779            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14780            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14781            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14782            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14783            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14784            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14785            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14786            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14787            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14788            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14789
14790            if (needSep) pw.println();
14791            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14792                    pw.print(" total, non-act at ");
14793                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14794                    pw.print(", non-svc at ");
14795                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14796                    pw.println("):");
14797            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14798            needSep = true;
14799        }
14800
14801        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14802
14803        pw.println();
14804        pw.println("  mHomeProcess: " + mHomeProcess);
14805        pw.println("  mPreviousProcess: " + mPreviousProcess);
14806        if (mHeavyWeightProcess != null) {
14807            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14808        }
14809
14810        return true;
14811    }
14812
14813    /**
14814     * There are three ways to call this:
14815     *  - no provider specified: dump all the providers
14816     *  - a flattened component name that matched an existing provider was specified as the
14817     *    first arg: dump that one provider
14818     *  - the first arg isn't the flattened component name of an existing provider:
14819     *    dump all providers whose component contains the first arg as a substring
14820     */
14821    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14822            int opti, boolean dumpAll) {
14823        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14824    }
14825
14826    static class ItemMatcher {
14827        ArrayList<ComponentName> components;
14828        ArrayList<String> strings;
14829        ArrayList<Integer> objects;
14830        boolean all;
14831
14832        ItemMatcher() {
14833            all = true;
14834        }
14835
14836        void build(String name) {
14837            ComponentName componentName = ComponentName.unflattenFromString(name);
14838            if (componentName != null) {
14839                if (components == null) {
14840                    components = new ArrayList<ComponentName>();
14841                }
14842                components.add(componentName);
14843                all = false;
14844            } else {
14845                int objectId = 0;
14846                // Not a '/' separated full component name; maybe an object ID?
14847                try {
14848                    objectId = Integer.parseInt(name, 16);
14849                    if (objects == null) {
14850                        objects = new ArrayList<Integer>();
14851                    }
14852                    objects.add(objectId);
14853                    all = false;
14854                } catch (RuntimeException e) {
14855                    // Not an integer; just do string match.
14856                    if (strings == null) {
14857                        strings = new ArrayList<String>();
14858                    }
14859                    strings.add(name);
14860                    all = false;
14861                }
14862            }
14863        }
14864
14865        int build(String[] args, int opti) {
14866            for (; opti<args.length; opti++) {
14867                String name = args[opti];
14868                if ("--".equals(name)) {
14869                    return opti+1;
14870                }
14871                build(name);
14872            }
14873            return opti;
14874        }
14875
14876        boolean match(Object object, ComponentName comp) {
14877            if (all) {
14878                return true;
14879            }
14880            if (components != null) {
14881                for (int i=0; i<components.size(); i++) {
14882                    if (components.get(i).equals(comp)) {
14883                        return true;
14884                    }
14885                }
14886            }
14887            if (objects != null) {
14888                for (int i=0; i<objects.size(); i++) {
14889                    if (System.identityHashCode(object) == objects.get(i)) {
14890                        return true;
14891                    }
14892                }
14893            }
14894            if (strings != null) {
14895                String flat = comp.flattenToString();
14896                for (int i=0; i<strings.size(); i++) {
14897                    if (flat.contains(strings.get(i))) {
14898                        return true;
14899                    }
14900                }
14901            }
14902            return false;
14903        }
14904    }
14905
14906    /**
14907     * There are three things that cmd can be:
14908     *  - a flattened component name that matches an existing activity
14909     *  - the cmd arg isn't the flattened component name of an existing activity:
14910     *    dump all activity whose component contains the cmd as a substring
14911     *  - A hex number of the ActivityRecord object instance.
14912     */
14913    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14914            int opti, boolean dumpAll) {
14915        ArrayList<ActivityRecord> activities;
14916
14917        synchronized (this) {
14918            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14919        }
14920
14921        if (activities.size() <= 0) {
14922            return false;
14923        }
14924
14925        String[] newArgs = new String[args.length - opti];
14926        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14927
14928        TaskRecord lastTask = null;
14929        boolean needSep = false;
14930        for (int i=activities.size()-1; i>=0; i--) {
14931            ActivityRecord r = activities.get(i);
14932            if (needSep) {
14933                pw.println();
14934            }
14935            needSep = true;
14936            synchronized (this) {
14937                if (lastTask != r.task) {
14938                    lastTask = r.task;
14939                    pw.print("TASK "); pw.print(lastTask.affinity);
14940                            pw.print(" id="); pw.println(lastTask.taskId);
14941                    if (dumpAll) {
14942                        lastTask.dump(pw, "  ");
14943                    }
14944                }
14945            }
14946            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14947        }
14948        return true;
14949    }
14950
14951    /**
14952     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14953     * there is a thread associated with the activity.
14954     */
14955    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14956            final ActivityRecord r, String[] args, boolean dumpAll) {
14957        String innerPrefix = prefix + "  ";
14958        synchronized (this) {
14959            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14960                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14961                    pw.print(" pid=");
14962                    if (r.app != null) pw.println(r.app.pid);
14963                    else pw.println("(not running)");
14964            if (dumpAll) {
14965                r.dump(pw, innerPrefix);
14966            }
14967        }
14968        if (r.app != null && r.app.thread != null) {
14969            // flush anything that is already in the PrintWriter since the thread is going
14970            // to write to the file descriptor directly
14971            pw.flush();
14972            try {
14973                TransferPipe tp = new TransferPipe();
14974                try {
14975                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14976                            r.appToken, innerPrefix, args);
14977                    tp.go(fd);
14978                } finally {
14979                    tp.kill();
14980                }
14981            } catch (IOException e) {
14982                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14983            } catch (RemoteException e) {
14984                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14985            }
14986        }
14987    }
14988
14989    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14990            int opti, boolean dumpAll, String dumpPackage) {
14991        boolean needSep = false;
14992        boolean onlyHistory = false;
14993        boolean printedAnything = false;
14994
14995        if ("history".equals(dumpPackage)) {
14996            if (opti < args.length && "-s".equals(args[opti])) {
14997                dumpAll = false;
14998            }
14999            onlyHistory = true;
15000            dumpPackage = null;
15001        }
15002
15003        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15004        if (!onlyHistory && dumpAll) {
15005            if (mRegisteredReceivers.size() > 0) {
15006                boolean printed = false;
15007                Iterator it = mRegisteredReceivers.values().iterator();
15008                while (it.hasNext()) {
15009                    ReceiverList r = (ReceiverList)it.next();
15010                    if (dumpPackage != null && (r.app == null ||
15011                            !dumpPackage.equals(r.app.info.packageName))) {
15012                        continue;
15013                    }
15014                    if (!printed) {
15015                        pw.println("  Registered Receivers:");
15016                        needSep = true;
15017                        printed = true;
15018                        printedAnything = true;
15019                    }
15020                    pw.print("  * "); pw.println(r);
15021                    r.dump(pw, "    ");
15022                }
15023            }
15024
15025            if (mReceiverResolver.dump(pw, needSep ?
15026                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15027                    "    ", dumpPackage, false, false)) {
15028                needSep = true;
15029                printedAnything = true;
15030            }
15031        }
15032
15033        for (BroadcastQueue q : mBroadcastQueues) {
15034            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15035            printedAnything |= needSep;
15036        }
15037
15038        needSep = true;
15039
15040        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15041            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15042                if (needSep) {
15043                    pw.println();
15044                }
15045                needSep = true;
15046                printedAnything = true;
15047                pw.print("  Sticky broadcasts for user ");
15048                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15049                StringBuilder sb = new StringBuilder(128);
15050                for (Map.Entry<String, ArrayList<Intent>> ent
15051                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15052                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15053                    if (dumpAll) {
15054                        pw.println(":");
15055                        ArrayList<Intent> intents = ent.getValue();
15056                        final int N = intents.size();
15057                        for (int i=0; i<N; i++) {
15058                            sb.setLength(0);
15059                            sb.append("    Intent: ");
15060                            intents.get(i).toShortString(sb, false, true, false, false);
15061                            pw.println(sb.toString());
15062                            Bundle bundle = intents.get(i).getExtras();
15063                            if (bundle != null) {
15064                                pw.print("      ");
15065                                pw.println(bundle.toString());
15066                            }
15067                        }
15068                    } else {
15069                        pw.println("");
15070                    }
15071                }
15072            }
15073        }
15074
15075        if (!onlyHistory && dumpAll) {
15076            pw.println();
15077            for (BroadcastQueue queue : mBroadcastQueues) {
15078                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15079                        + queue.mBroadcastsScheduled);
15080            }
15081            pw.println("  mHandler:");
15082            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15083            needSep = true;
15084            printedAnything = true;
15085        }
15086
15087        if (!printedAnything) {
15088            pw.println("  (nothing)");
15089        }
15090    }
15091
15092    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15093            int opti, boolean dumpAll, String dumpPackage) {
15094        if (mCurBroadcastStats == null) {
15095            return;
15096        }
15097
15098        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15099        final long now = SystemClock.elapsedRealtime();
15100        if (mLastBroadcastStats != null) {
15101            pw.print("  Last stats (from ");
15102            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15103            pw.print(" to ");
15104            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15105            pw.print(", ");
15106            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15107                    - mLastBroadcastStats.mStartUptime, pw);
15108            pw.println(" uptime):");
15109            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15110                pw.println("    (nothing)");
15111            }
15112            pw.println();
15113        }
15114        pw.print("  Current stats (from ");
15115        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15116        pw.print(" to now, ");
15117        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15118                - mCurBroadcastStats.mStartUptime, pw);
15119        pw.println(" uptime):");
15120        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15121            pw.println("    (nothing)");
15122        }
15123    }
15124
15125    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15126            int opti, boolean fullCheckin, String dumpPackage) {
15127        if (mCurBroadcastStats == null) {
15128            return;
15129        }
15130
15131        if (mLastBroadcastStats != null) {
15132            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15133            if (fullCheckin) {
15134                mLastBroadcastStats = null;
15135                return;
15136            }
15137        }
15138        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15139        if (fullCheckin) {
15140            mCurBroadcastStats = null;
15141        }
15142    }
15143
15144    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15145            int opti, boolean dumpAll, String dumpPackage) {
15146        boolean needSep;
15147        boolean printedAnything = false;
15148
15149        ItemMatcher matcher = new ItemMatcher();
15150        matcher.build(args, opti);
15151
15152        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15153
15154        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15155        printedAnything |= needSep;
15156
15157        if (mLaunchingProviders.size() > 0) {
15158            boolean printed = false;
15159            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15160                ContentProviderRecord r = mLaunchingProviders.get(i);
15161                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15162                    continue;
15163                }
15164                if (!printed) {
15165                    if (needSep) pw.println();
15166                    needSep = true;
15167                    pw.println("  Launching content providers:");
15168                    printed = true;
15169                    printedAnything = true;
15170                }
15171                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15172                        pw.println(r);
15173            }
15174        }
15175
15176        if (!printedAnything) {
15177            pw.println("  (nothing)");
15178        }
15179    }
15180
15181    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15182            int opti, boolean dumpAll, String dumpPackage) {
15183        boolean needSep = false;
15184        boolean printedAnything = false;
15185
15186        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15187
15188        if (mGrantedUriPermissions.size() > 0) {
15189            boolean printed = false;
15190            int dumpUid = -2;
15191            if (dumpPackage != null) {
15192                try {
15193                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15194                            MATCH_UNINSTALLED_PACKAGES, 0);
15195                } catch (NameNotFoundException e) {
15196                    dumpUid = -1;
15197                }
15198            }
15199            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15200                int uid = mGrantedUriPermissions.keyAt(i);
15201                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15202                    continue;
15203                }
15204                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15205                if (!printed) {
15206                    if (needSep) pw.println();
15207                    needSep = true;
15208                    pw.println("  Granted Uri Permissions:");
15209                    printed = true;
15210                    printedAnything = true;
15211                }
15212                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15213                for (UriPermission perm : perms.values()) {
15214                    pw.print("    "); pw.println(perm);
15215                    if (dumpAll) {
15216                        perm.dump(pw, "      ");
15217                    }
15218                }
15219            }
15220        }
15221
15222        if (!printedAnything) {
15223            pw.println("  (nothing)");
15224        }
15225    }
15226
15227    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15228            int opti, boolean dumpAll, String dumpPackage) {
15229        boolean printed = false;
15230
15231        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15232
15233        if (mIntentSenderRecords.size() > 0) {
15234            Iterator<WeakReference<PendingIntentRecord>> it
15235                    = mIntentSenderRecords.values().iterator();
15236            while (it.hasNext()) {
15237                WeakReference<PendingIntentRecord> ref = it.next();
15238                PendingIntentRecord rec = ref != null ? ref.get(): null;
15239                if (dumpPackage != null && (rec == null
15240                        || !dumpPackage.equals(rec.key.packageName))) {
15241                    continue;
15242                }
15243                printed = true;
15244                if (rec != null) {
15245                    pw.print("  * "); pw.println(rec);
15246                    if (dumpAll) {
15247                        rec.dump(pw, "    ");
15248                    }
15249                } else {
15250                    pw.print("  * "); pw.println(ref);
15251                }
15252            }
15253        }
15254
15255        if (!printed) {
15256            pw.println("  (nothing)");
15257        }
15258    }
15259
15260    private static final int dumpProcessList(PrintWriter pw,
15261            ActivityManagerService service, List list,
15262            String prefix, String normalLabel, String persistentLabel,
15263            String dumpPackage) {
15264        int numPers = 0;
15265        final int N = list.size()-1;
15266        for (int i=N; i>=0; i--) {
15267            ProcessRecord r = (ProcessRecord)list.get(i);
15268            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15269                continue;
15270            }
15271            pw.println(String.format("%s%s #%2d: %s",
15272                    prefix, (r.persistent ? persistentLabel : normalLabel),
15273                    i, r.toString()));
15274            if (r.persistent) {
15275                numPers++;
15276            }
15277        }
15278        return numPers;
15279    }
15280
15281    private static final boolean dumpProcessOomList(PrintWriter pw,
15282            ActivityManagerService service, List<ProcessRecord> origList,
15283            String prefix, String normalLabel, String persistentLabel,
15284            boolean inclDetails, String dumpPackage) {
15285
15286        ArrayList<Pair<ProcessRecord, Integer>> list
15287                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15288        for (int i=0; i<origList.size(); i++) {
15289            ProcessRecord r = origList.get(i);
15290            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15291                continue;
15292            }
15293            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15294        }
15295
15296        if (list.size() <= 0) {
15297            return false;
15298        }
15299
15300        Comparator<Pair<ProcessRecord, Integer>> comparator
15301                = new Comparator<Pair<ProcessRecord, Integer>>() {
15302            @Override
15303            public int compare(Pair<ProcessRecord, Integer> object1,
15304                    Pair<ProcessRecord, Integer> object2) {
15305                if (object1.first.setAdj != object2.first.setAdj) {
15306                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15307                }
15308                if (object1.first.setProcState != object2.first.setProcState) {
15309                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15310                }
15311                if (object1.second.intValue() != object2.second.intValue()) {
15312                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15313                }
15314                return 0;
15315            }
15316        };
15317
15318        Collections.sort(list, comparator);
15319
15320        final long curRealtime = SystemClock.elapsedRealtime();
15321        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15322        final long curUptime = SystemClock.uptimeMillis();
15323        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15324
15325        for (int i=list.size()-1; i>=0; i--) {
15326            ProcessRecord r = list.get(i).first;
15327            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15328            char schedGroup;
15329            switch (r.setSchedGroup) {
15330                case ProcessList.SCHED_GROUP_BACKGROUND:
15331                    schedGroup = 'B';
15332                    break;
15333                case ProcessList.SCHED_GROUP_DEFAULT:
15334                    schedGroup = 'F';
15335                    break;
15336                case ProcessList.SCHED_GROUP_TOP_APP:
15337                    schedGroup = 'T';
15338                    break;
15339                default:
15340                    schedGroup = '?';
15341                    break;
15342            }
15343            char foreground;
15344            if (r.foregroundActivities) {
15345                foreground = 'A';
15346            } else if (r.foregroundServices) {
15347                foreground = 'S';
15348            } else {
15349                foreground = ' ';
15350            }
15351            String procState = ProcessList.makeProcStateString(r.curProcState);
15352            pw.print(prefix);
15353            pw.print(r.persistent ? persistentLabel : normalLabel);
15354            pw.print(" #");
15355            int num = (origList.size()-1)-list.get(i).second;
15356            if (num < 10) pw.print(' ');
15357            pw.print(num);
15358            pw.print(": ");
15359            pw.print(oomAdj);
15360            pw.print(' ');
15361            pw.print(schedGroup);
15362            pw.print('/');
15363            pw.print(foreground);
15364            pw.print('/');
15365            pw.print(procState);
15366            pw.print(" trm:");
15367            if (r.trimMemoryLevel < 10) pw.print(' ');
15368            pw.print(r.trimMemoryLevel);
15369            pw.print(' ');
15370            pw.print(r.toShortString());
15371            pw.print(" (");
15372            pw.print(r.adjType);
15373            pw.println(')');
15374            if (r.adjSource != null || r.adjTarget != null) {
15375                pw.print(prefix);
15376                pw.print("    ");
15377                if (r.adjTarget instanceof ComponentName) {
15378                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15379                } else if (r.adjTarget != null) {
15380                    pw.print(r.adjTarget.toString());
15381                } else {
15382                    pw.print("{null}");
15383                }
15384                pw.print("<=");
15385                if (r.adjSource instanceof ProcessRecord) {
15386                    pw.print("Proc{");
15387                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15388                    pw.println("}");
15389                } else if (r.adjSource != null) {
15390                    pw.println(r.adjSource.toString());
15391                } else {
15392                    pw.println("{null}");
15393                }
15394            }
15395            if (inclDetails) {
15396                pw.print(prefix);
15397                pw.print("    ");
15398                pw.print("oom: max="); pw.print(r.maxAdj);
15399                pw.print(" curRaw="); pw.print(r.curRawAdj);
15400                pw.print(" setRaw="); pw.print(r.setRawAdj);
15401                pw.print(" cur="); pw.print(r.curAdj);
15402                pw.print(" set="); pw.println(r.setAdj);
15403                pw.print(prefix);
15404                pw.print("    ");
15405                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15406                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15407                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15408                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15409                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15410                pw.println();
15411                pw.print(prefix);
15412                pw.print("    ");
15413                pw.print("cached="); pw.print(r.cached);
15414                pw.print(" empty="); pw.print(r.empty);
15415                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15416
15417                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15418                    if (r.lastWakeTime != 0) {
15419                        long wtime;
15420                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15421                        synchronized (stats) {
15422                            wtime = stats.getProcessWakeTime(r.info.uid,
15423                                    r.pid, curRealtime);
15424                        }
15425                        long timeUsed = wtime - r.lastWakeTime;
15426                        pw.print(prefix);
15427                        pw.print("    ");
15428                        pw.print("keep awake over ");
15429                        TimeUtils.formatDuration(realtimeSince, pw);
15430                        pw.print(" used ");
15431                        TimeUtils.formatDuration(timeUsed, pw);
15432                        pw.print(" (");
15433                        pw.print((timeUsed*100)/realtimeSince);
15434                        pw.println("%)");
15435                    }
15436                    if (r.lastCpuTime != 0) {
15437                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15438                        pw.print(prefix);
15439                        pw.print("    ");
15440                        pw.print("run cpu over ");
15441                        TimeUtils.formatDuration(uptimeSince, pw);
15442                        pw.print(" used ");
15443                        TimeUtils.formatDuration(timeUsed, pw);
15444                        pw.print(" (");
15445                        pw.print((timeUsed*100)/uptimeSince);
15446                        pw.println("%)");
15447                    }
15448                }
15449            }
15450        }
15451        return true;
15452    }
15453
15454    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15455            String[] args) {
15456        ArrayList<ProcessRecord> procs;
15457        synchronized (this) {
15458            if (args != null && args.length > start
15459                    && args[start].charAt(0) != '-') {
15460                procs = new ArrayList<ProcessRecord>();
15461                int pid = -1;
15462                try {
15463                    pid = Integer.parseInt(args[start]);
15464                } catch (NumberFormatException e) {
15465                }
15466                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15467                    ProcessRecord proc = mLruProcesses.get(i);
15468                    if (proc.pid == pid) {
15469                        procs.add(proc);
15470                    } else if (allPkgs && proc.pkgList != null
15471                            && proc.pkgList.containsKey(args[start])) {
15472                        procs.add(proc);
15473                    } else if (proc.processName.equals(args[start])) {
15474                        procs.add(proc);
15475                    }
15476                }
15477                if (procs.size() <= 0) {
15478                    return null;
15479                }
15480            } else {
15481                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15482            }
15483        }
15484        return procs;
15485    }
15486
15487    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15488            PrintWriter pw, String[] args) {
15489        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15490        if (procs == null) {
15491            pw.println("No process found for: " + args[0]);
15492            return;
15493        }
15494
15495        long uptime = SystemClock.uptimeMillis();
15496        long realtime = SystemClock.elapsedRealtime();
15497        pw.println("Applications Graphics Acceleration Info:");
15498        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15499
15500        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15501            ProcessRecord r = procs.get(i);
15502            if (r.thread != null) {
15503                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15504                pw.flush();
15505                try {
15506                    TransferPipe tp = new TransferPipe();
15507                    try {
15508                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15509                        tp.go(fd);
15510                    } finally {
15511                        tp.kill();
15512                    }
15513                } catch (IOException e) {
15514                    pw.println("Failure while dumping the app: " + r);
15515                    pw.flush();
15516                } catch (RemoteException e) {
15517                    pw.println("Got a RemoteException while dumping the app " + r);
15518                    pw.flush();
15519                }
15520            }
15521        }
15522    }
15523
15524    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15525        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15526        if (procs == null) {
15527            pw.println("No process found for: " + args[0]);
15528            return;
15529        }
15530
15531        pw.println("Applications Database Info:");
15532
15533        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15534            ProcessRecord r = procs.get(i);
15535            if (r.thread != null) {
15536                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15537                pw.flush();
15538                try {
15539                    TransferPipe tp = new TransferPipe();
15540                    try {
15541                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15542                        tp.go(fd);
15543                    } finally {
15544                        tp.kill();
15545                    }
15546                } catch (IOException e) {
15547                    pw.println("Failure while dumping the app: " + r);
15548                    pw.flush();
15549                } catch (RemoteException e) {
15550                    pw.println("Got a RemoteException while dumping the app " + r);
15551                    pw.flush();
15552                }
15553            }
15554        }
15555    }
15556
15557    final static class MemItem {
15558        final boolean isProc;
15559        final String label;
15560        final String shortLabel;
15561        final long pss;
15562        final long swapPss;
15563        final int id;
15564        final boolean hasActivities;
15565        ArrayList<MemItem> subitems;
15566
15567        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15568                boolean _hasActivities) {
15569            isProc = true;
15570            label = _label;
15571            shortLabel = _shortLabel;
15572            pss = _pss;
15573            swapPss = _swapPss;
15574            id = _id;
15575            hasActivities = _hasActivities;
15576        }
15577
15578        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15579            isProc = false;
15580            label = _label;
15581            shortLabel = _shortLabel;
15582            pss = _pss;
15583            swapPss = _swapPss;
15584            id = _id;
15585            hasActivities = false;
15586        }
15587    }
15588
15589    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15590            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15591        if (sort && !isCompact) {
15592            Collections.sort(items, new Comparator<MemItem>() {
15593                @Override
15594                public int compare(MemItem lhs, MemItem rhs) {
15595                    if (lhs.pss < rhs.pss) {
15596                        return 1;
15597                    } else if (lhs.pss > rhs.pss) {
15598                        return -1;
15599                    }
15600                    return 0;
15601                }
15602            });
15603        }
15604
15605        for (int i=0; i<items.size(); i++) {
15606            MemItem mi = items.get(i);
15607            if (!isCompact) {
15608                if (dumpSwapPss) {
15609                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15610                            mi.label, stringifyKBSize(mi.swapPss));
15611                } else {
15612                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15613                }
15614            } else if (mi.isProc) {
15615                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15616                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15617                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15618                pw.println(mi.hasActivities ? ",a" : ",e");
15619            } else {
15620                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15621                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15622            }
15623            if (mi.subitems != null) {
15624                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15625                        true, isCompact, dumpSwapPss);
15626            }
15627        }
15628    }
15629
15630    // These are in KB.
15631    static final long[] DUMP_MEM_BUCKETS = new long[] {
15632        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15633        120*1024, 160*1024, 200*1024,
15634        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15635        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15636    };
15637
15638    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15639            boolean stackLike) {
15640        int start = label.lastIndexOf('.');
15641        if (start >= 0) start++;
15642        else start = 0;
15643        int end = label.length();
15644        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15645            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15646                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15647                out.append(bucket);
15648                out.append(stackLike ? "MB." : "MB ");
15649                out.append(label, start, end);
15650                return;
15651            }
15652        }
15653        out.append(memKB/1024);
15654        out.append(stackLike ? "MB." : "MB ");
15655        out.append(label, start, end);
15656    }
15657
15658    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15659            ProcessList.NATIVE_ADJ,
15660            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15661            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15662            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15663            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15664            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15665            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15666    };
15667    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15668            "Native",
15669            "System", "Persistent", "Persistent Service", "Foreground",
15670            "Visible", "Perceptible",
15671            "Heavy Weight", "Backup",
15672            "A Services", "Home",
15673            "Previous", "B Services", "Cached"
15674    };
15675    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15676            "native",
15677            "sys", "pers", "persvc", "fore",
15678            "vis", "percept",
15679            "heavy", "backup",
15680            "servicea", "home",
15681            "prev", "serviceb", "cached"
15682    };
15683
15684    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15685            long realtime, boolean isCheckinRequest, boolean isCompact) {
15686        if (isCompact) {
15687            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15688        }
15689        if (isCheckinRequest || isCompact) {
15690            // short checkin version
15691            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15692        } else {
15693            pw.println("Applications Memory Usage (in Kilobytes):");
15694            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15695        }
15696    }
15697
15698    private static final int KSM_SHARED = 0;
15699    private static final int KSM_SHARING = 1;
15700    private static final int KSM_UNSHARED = 2;
15701    private static final int KSM_VOLATILE = 3;
15702
15703    private final long[] getKsmInfo() {
15704        long[] longOut = new long[4];
15705        final int[] SINGLE_LONG_FORMAT = new int[] {
15706            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15707        };
15708        long[] longTmp = new long[1];
15709        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15710                SINGLE_LONG_FORMAT, null, longTmp, null);
15711        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15712        longTmp[0] = 0;
15713        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15714                SINGLE_LONG_FORMAT, null, longTmp, null);
15715        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15716        longTmp[0] = 0;
15717        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15718                SINGLE_LONG_FORMAT, null, longTmp, null);
15719        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15720        longTmp[0] = 0;
15721        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15722                SINGLE_LONG_FORMAT, null, longTmp, null);
15723        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15724        return longOut;
15725    }
15726
15727    private static String stringifySize(long size, int order) {
15728        Locale locale = Locale.US;
15729        switch (order) {
15730            case 1:
15731                return String.format(locale, "%,13d", size);
15732            case 1024:
15733                return String.format(locale, "%,9dK", size / 1024);
15734            case 1024 * 1024:
15735                return String.format(locale, "%,5dM", size / 1024 / 1024);
15736            case 1024 * 1024 * 1024:
15737                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15738            default:
15739                throw new IllegalArgumentException("Invalid size order");
15740        }
15741    }
15742
15743    private static String stringifyKBSize(long size) {
15744        return stringifySize(size * 1024, 1024);
15745    }
15746
15747    // Update this version number in case you change the 'compact' format
15748    private static final int MEMINFO_COMPACT_VERSION = 1;
15749
15750    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15751            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15752        boolean dumpDetails = false;
15753        boolean dumpFullDetails = false;
15754        boolean dumpDalvik = false;
15755        boolean dumpSummaryOnly = false;
15756        boolean dumpUnreachable = false;
15757        boolean oomOnly = false;
15758        boolean isCompact = false;
15759        boolean localOnly = false;
15760        boolean packages = false;
15761        boolean isCheckinRequest = false;
15762        boolean dumpSwapPss = false;
15763
15764        int opti = 0;
15765        while (opti < args.length) {
15766            String opt = args[opti];
15767            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15768                break;
15769            }
15770            opti++;
15771            if ("-a".equals(opt)) {
15772                dumpDetails = true;
15773                dumpFullDetails = true;
15774                dumpDalvik = true;
15775                dumpSwapPss = true;
15776            } else if ("-d".equals(opt)) {
15777                dumpDalvik = true;
15778            } else if ("-c".equals(opt)) {
15779                isCompact = true;
15780            } else if ("-s".equals(opt)) {
15781                dumpDetails = true;
15782                dumpSummaryOnly = true;
15783            } else if ("-S".equals(opt)) {
15784                dumpSwapPss = true;
15785            } else if ("--unreachable".equals(opt)) {
15786                dumpUnreachable = true;
15787            } else if ("--oom".equals(opt)) {
15788                oomOnly = true;
15789            } else if ("--local".equals(opt)) {
15790                localOnly = true;
15791            } else if ("--package".equals(opt)) {
15792                packages = true;
15793            } else if ("--checkin".equals(opt)) {
15794                isCheckinRequest = true;
15795
15796            } else if ("-h".equals(opt)) {
15797                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15798                pw.println("  -a: include all available information for each process.");
15799                pw.println("  -d: include dalvik details.");
15800                pw.println("  -c: dump in a compact machine-parseable representation.");
15801                pw.println("  -s: dump only summary of application memory usage.");
15802                pw.println("  -S: dump also SwapPss.");
15803                pw.println("  --oom: only show processes organized by oom adj.");
15804                pw.println("  --local: only collect details locally, don't call process.");
15805                pw.println("  --package: interpret process arg as package, dumping all");
15806                pw.println("             processes that have loaded that package.");
15807                pw.println("  --checkin: dump data for a checkin");
15808                pw.println("If [process] is specified it can be the name or ");
15809                pw.println("pid of a specific process to dump.");
15810                return;
15811            } else {
15812                pw.println("Unknown argument: " + opt + "; use -h for help");
15813            }
15814        }
15815
15816        long uptime = SystemClock.uptimeMillis();
15817        long realtime = SystemClock.elapsedRealtime();
15818        final long[] tmpLong = new long[1];
15819
15820        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15821        if (procs == null) {
15822            // No Java processes.  Maybe they want to print a native process.
15823            if (args != null && args.length > opti
15824                    && args[opti].charAt(0) != '-') {
15825                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15826                        = new ArrayList<ProcessCpuTracker.Stats>();
15827                updateCpuStatsNow();
15828                int findPid = -1;
15829                try {
15830                    findPid = Integer.parseInt(args[opti]);
15831                } catch (NumberFormatException e) {
15832                }
15833                synchronized (mProcessCpuTracker) {
15834                    final int N = mProcessCpuTracker.countStats();
15835                    for (int i=0; i<N; i++) {
15836                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15837                        if (st.pid == findPid || (st.baseName != null
15838                                && st.baseName.equals(args[opti]))) {
15839                            nativeProcs.add(st);
15840                        }
15841                    }
15842                }
15843                if (nativeProcs.size() > 0) {
15844                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15845                            isCompact);
15846                    Debug.MemoryInfo mi = null;
15847                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15848                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15849                        final int pid = r.pid;
15850                        if (!isCheckinRequest && dumpDetails) {
15851                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15852                        }
15853                        if (mi == null) {
15854                            mi = new Debug.MemoryInfo();
15855                        }
15856                        if (dumpDetails || (!brief && !oomOnly)) {
15857                            Debug.getMemoryInfo(pid, mi);
15858                        } else {
15859                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15860                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15861                        }
15862                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15863                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15864                        if (isCheckinRequest) {
15865                            pw.println();
15866                        }
15867                    }
15868                    return;
15869                }
15870            }
15871            pw.println("No process found for: " + args[opti]);
15872            return;
15873        }
15874
15875        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15876            dumpDetails = true;
15877        }
15878
15879        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15880
15881        String[] innerArgs = new String[args.length-opti];
15882        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15883
15884        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15885        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15886        long nativePss = 0;
15887        long nativeSwapPss = 0;
15888        long dalvikPss = 0;
15889        long dalvikSwapPss = 0;
15890        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15891                EmptyArray.LONG;
15892        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15893                EmptyArray.LONG;
15894        long otherPss = 0;
15895        long otherSwapPss = 0;
15896        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15897        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15898
15899        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15900        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15901        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15902                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15903
15904        long totalPss = 0;
15905        long totalSwapPss = 0;
15906        long cachedPss = 0;
15907        long cachedSwapPss = 0;
15908        boolean hasSwapPss = false;
15909
15910        Debug.MemoryInfo mi = null;
15911        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15912            final ProcessRecord r = procs.get(i);
15913            final IApplicationThread thread;
15914            final int pid;
15915            final int oomAdj;
15916            final boolean hasActivities;
15917            synchronized (this) {
15918                thread = r.thread;
15919                pid = r.pid;
15920                oomAdj = r.getSetAdjWithServices();
15921                hasActivities = r.activities.size() > 0;
15922            }
15923            if (thread != null) {
15924                if (!isCheckinRequest && dumpDetails) {
15925                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15926                }
15927                if (mi == null) {
15928                    mi = new Debug.MemoryInfo();
15929                }
15930                if (dumpDetails || (!brief && !oomOnly)) {
15931                    Debug.getMemoryInfo(pid, mi);
15932                    hasSwapPss = mi.hasSwappedOutPss;
15933                } else {
15934                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15935                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15936                }
15937                if (dumpDetails) {
15938                    if (localOnly) {
15939                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15940                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15941                        if (isCheckinRequest) {
15942                            pw.println();
15943                        }
15944                    } else {
15945                        try {
15946                            pw.flush();
15947                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15948                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15949                        } catch (RemoteException e) {
15950                            if (!isCheckinRequest) {
15951                                pw.println("Got RemoteException!");
15952                                pw.flush();
15953                            }
15954                        }
15955                    }
15956                }
15957
15958                final long myTotalPss = mi.getTotalPss();
15959                final long myTotalUss = mi.getTotalUss();
15960                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15961
15962                synchronized (this) {
15963                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15964                        // Record this for posterity if the process has been stable.
15965                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15966                    }
15967                }
15968
15969                if (!isCheckinRequest && mi != null) {
15970                    totalPss += myTotalPss;
15971                    totalSwapPss += myTotalSwapPss;
15972                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15973                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15974                            myTotalSwapPss, pid, hasActivities);
15975                    procMems.add(pssItem);
15976                    procMemsMap.put(pid, pssItem);
15977
15978                    nativePss += mi.nativePss;
15979                    nativeSwapPss += mi.nativeSwappedOutPss;
15980                    dalvikPss += mi.dalvikPss;
15981                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15982                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15983                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15984                        dalvikSubitemSwapPss[j] +=
15985                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15986                    }
15987                    otherPss += mi.otherPss;
15988                    otherSwapPss += mi.otherSwappedOutPss;
15989                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15990                        long mem = mi.getOtherPss(j);
15991                        miscPss[j] += mem;
15992                        otherPss -= mem;
15993                        mem = mi.getOtherSwappedOutPss(j);
15994                        miscSwapPss[j] += mem;
15995                        otherSwapPss -= mem;
15996                    }
15997
15998                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15999                        cachedPss += myTotalPss;
16000                        cachedSwapPss += myTotalSwapPss;
16001                    }
16002
16003                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16004                        if (oomIndex == (oomPss.length - 1)
16005                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16006                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16007                            oomPss[oomIndex] += myTotalPss;
16008                            oomSwapPss[oomIndex] += myTotalSwapPss;
16009                            if (oomProcs[oomIndex] == null) {
16010                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16011                            }
16012                            oomProcs[oomIndex].add(pssItem);
16013                            break;
16014                        }
16015                    }
16016                }
16017            }
16018        }
16019
16020        long nativeProcTotalPss = 0;
16021
16022        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16023            // If we are showing aggregations, also look for native processes to
16024            // include so that our aggregations are more accurate.
16025            updateCpuStatsNow();
16026            mi = null;
16027            synchronized (mProcessCpuTracker) {
16028                final int N = mProcessCpuTracker.countStats();
16029                for (int i=0; i<N; i++) {
16030                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16031                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16032                        if (mi == null) {
16033                            mi = new Debug.MemoryInfo();
16034                        }
16035                        if (!brief && !oomOnly) {
16036                            Debug.getMemoryInfo(st.pid, mi);
16037                        } else {
16038                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16039                            mi.nativePrivateDirty = (int)tmpLong[0];
16040                        }
16041
16042                        final long myTotalPss = mi.getTotalPss();
16043                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16044                        totalPss += myTotalPss;
16045                        nativeProcTotalPss += myTotalPss;
16046
16047                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16048                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16049                        procMems.add(pssItem);
16050
16051                        nativePss += mi.nativePss;
16052                        nativeSwapPss += mi.nativeSwappedOutPss;
16053                        dalvikPss += mi.dalvikPss;
16054                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16055                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16056                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16057                            dalvikSubitemSwapPss[j] +=
16058                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16059                        }
16060                        otherPss += mi.otherPss;
16061                        otherSwapPss += mi.otherSwappedOutPss;
16062                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16063                            long mem = mi.getOtherPss(j);
16064                            miscPss[j] += mem;
16065                            otherPss -= mem;
16066                            mem = mi.getOtherSwappedOutPss(j);
16067                            miscSwapPss[j] += mem;
16068                            otherSwapPss -= mem;
16069                        }
16070                        oomPss[0] += myTotalPss;
16071                        oomSwapPss[0] += myTotalSwapPss;
16072                        if (oomProcs[0] == null) {
16073                            oomProcs[0] = new ArrayList<MemItem>();
16074                        }
16075                        oomProcs[0].add(pssItem);
16076                    }
16077                }
16078            }
16079
16080            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16081
16082            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16083            final MemItem dalvikItem =
16084                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16085            if (dalvikSubitemPss.length > 0) {
16086                dalvikItem.subitems = new ArrayList<MemItem>();
16087                for (int j=0; j<dalvikSubitemPss.length; j++) {
16088                    final String name = Debug.MemoryInfo.getOtherLabel(
16089                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16090                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16091                                    dalvikSubitemSwapPss[j], j));
16092                }
16093            }
16094            catMems.add(dalvikItem);
16095            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16096            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16097                String label = Debug.MemoryInfo.getOtherLabel(j);
16098                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16099            }
16100
16101            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16102            for (int j=0; j<oomPss.length; j++) {
16103                if (oomPss[j] != 0) {
16104                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16105                            : DUMP_MEM_OOM_LABEL[j];
16106                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16107                            DUMP_MEM_OOM_ADJ[j]);
16108                    item.subitems = oomProcs[j];
16109                    oomMems.add(item);
16110                }
16111            }
16112
16113            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16114            if (!brief && !oomOnly && !isCompact) {
16115                pw.println();
16116                pw.println("Total PSS by process:");
16117                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16118                pw.println();
16119            }
16120            if (!isCompact) {
16121                pw.println("Total PSS by OOM adjustment:");
16122            }
16123            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16124            if (!brief && !oomOnly) {
16125                PrintWriter out = categoryPw != null ? categoryPw : pw;
16126                if (!isCompact) {
16127                    out.println();
16128                    out.println("Total PSS by category:");
16129                }
16130                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16131            }
16132            if (!isCompact) {
16133                pw.println();
16134            }
16135            MemInfoReader memInfo = new MemInfoReader();
16136            memInfo.readMemInfo();
16137            if (nativeProcTotalPss > 0) {
16138                synchronized (this) {
16139                    final long cachedKb = memInfo.getCachedSizeKb();
16140                    final long freeKb = memInfo.getFreeSizeKb();
16141                    final long zramKb = memInfo.getZramTotalSizeKb();
16142                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16143                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16144                            kernelKb*1024, nativeProcTotalPss*1024);
16145                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16146                            nativeProcTotalPss);
16147                }
16148            }
16149            if (!brief) {
16150                if (!isCompact) {
16151                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16152                    pw.print(" (status ");
16153                    switch (mLastMemoryLevel) {
16154                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16155                            pw.println("normal)");
16156                            break;
16157                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16158                            pw.println("moderate)");
16159                            break;
16160                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16161                            pw.println("low)");
16162                            break;
16163                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16164                            pw.println("critical)");
16165                            break;
16166                        default:
16167                            pw.print(mLastMemoryLevel);
16168                            pw.println(")");
16169                            break;
16170                    }
16171                    pw.print(" Free RAM: ");
16172                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16173                            + memInfo.getFreeSizeKb()));
16174                    pw.print(" (");
16175                    pw.print(stringifyKBSize(cachedPss));
16176                    pw.print(" cached pss + ");
16177                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16178                    pw.print(" cached kernel + ");
16179                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16180                    pw.println(" free)");
16181                } else {
16182                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16183                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16184                            + memInfo.getFreeSizeKb()); pw.print(",");
16185                    pw.println(totalPss - cachedPss);
16186                }
16187            }
16188            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16189                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16190                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16191            if (!isCompact) {
16192                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16193                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16194                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16195                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16196                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16197            } else {
16198                pw.print("lostram,"); pw.println(lostRAM);
16199            }
16200            if (!brief) {
16201                if (memInfo.getZramTotalSizeKb() != 0) {
16202                    if (!isCompact) {
16203                        pw.print("     ZRAM: ");
16204                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16205                                pw.print(" physical used for ");
16206                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16207                                        - memInfo.getSwapFreeSizeKb()));
16208                                pw.print(" in swap (");
16209                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16210                                pw.println(" total swap)");
16211                    } else {
16212                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16213                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16214                                pw.println(memInfo.getSwapFreeSizeKb());
16215                    }
16216                }
16217                final long[] ksm = getKsmInfo();
16218                if (!isCompact) {
16219                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16220                            || ksm[KSM_VOLATILE] != 0) {
16221                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16222                                pw.print(" saved from shared ");
16223                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16224                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16225                                pw.print(" unshared; ");
16226                                pw.print(stringifyKBSize(
16227                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16228                    }
16229                    pw.print("   Tuning: ");
16230                    pw.print(ActivityManager.staticGetMemoryClass());
16231                    pw.print(" (large ");
16232                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16233                    pw.print("), oom ");
16234                    pw.print(stringifySize(
16235                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16236                    pw.print(", restore limit ");
16237                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16238                    if (ActivityManager.isLowRamDeviceStatic()) {
16239                        pw.print(" (low-ram)");
16240                    }
16241                    if (ActivityManager.isHighEndGfx()) {
16242                        pw.print(" (high-end-gfx)");
16243                    }
16244                    pw.println();
16245                } else {
16246                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16247                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16248                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16249                    pw.print("tuning,");
16250                    pw.print(ActivityManager.staticGetMemoryClass());
16251                    pw.print(',');
16252                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16253                    pw.print(',');
16254                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16255                    if (ActivityManager.isLowRamDeviceStatic()) {
16256                        pw.print(",low-ram");
16257                    }
16258                    if (ActivityManager.isHighEndGfx()) {
16259                        pw.print(",high-end-gfx");
16260                    }
16261                    pw.println();
16262                }
16263            }
16264        }
16265    }
16266
16267    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16268            long memtrack, String name) {
16269        sb.append("  ");
16270        sb.append(ProcessList.makeOomAdjString(oomAdj));
16271        sb.append(' ');
16272        sb.append(ProcessList.makeProcStateString(procState));
16273        sb.append(' ');
16274        ProcessList.appendRamKb(sb, pss);
16275        sb.append(": ");
16276        sb.append(name);
16277        if (memtrack > 0) {
16278            sb.append(" (");
16279            sb.append(stringifyKBSize(memtrack));
16280            sb.append(" memtrack)");
16281        }
16282    }
16283
16284    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16285        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16286        sb.append(" (pid ");
16287        sb.append(mi.pid);
16288        sb.append(") ");
16289        sb.append(mi.adjType);
16290        sb.append('\n');
16291        if (mi.adjReason != null) {
16292            sb.append("                      ");
16293            sb.append(mi.adjReason);
16294            sb.append('\n');
16295        }
16296    }
16297
16298    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16299        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16300        for (int i=0, N=memInfos.size(); i<N; i++) {
16301            ProcessMemInfo mi = memInfos.get(i);
16302            infoMap.put(mi.pid, mi);
16303        }
16304        updateCpuStatsNow();
16305        long[] memtrackTmp = new long[1];
16306        synchronized (mProcessCpuTracker) {
16307            final int N = mProcessCpuTracker.countStats();
16308            for (int i=0; i<N; i++) {
16309                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16310                if (st.vsize > 0) {
16311                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16312                    if (pss > 0) {
16313                        if (infoMap.indexOfKey(st.pid) < 0) {
16314                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16315                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16316                            mi.pss = pss;
16317                            mi.memtrack = memtrackTmp[0];
16318                            memInfos.add(mi);
16319                        }
16320                    }
16321                }
16322            }
16323        }
16324
16325        long totalPss = 0;
16326        long totalMemtrack = 0;
16327        for (int i=0, N=memInfos.size(); i<N; i++) {
16328            ProcessMemInfo mi = memInfos.get(i);
16329            if (mi.pss == 0) {
16330                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16331                mi.memtrack = memtrackTmp[0];
16332            }
16333            totalPss += mi.pss;
16334            totalMemtrack += mi.memtrack;
16335        }
16336        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16337            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16338                if (lhs.oomAdj != rhs.oomAdj) {
16339                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16340                }
16341                if (lhs.pss != rhs.pss) {
16342                    return lhs.pss < rhs.pss ? 1 : -1;
16343                }
16344                return 0;
16345            }
16346        });
16347
16348        StringBuilder tag = new StringBuilder(128);
16349        StringBuilder stack = new StringBuilder(128);
16350        tag.append("Low on memory -- ");
16351        appendMemBucket(tag, totalPss, "total", false);
16352        appendMemBucket(stack, totalPss, "total", true);
16353
16354        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16355        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16356        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16357
16358        boolean firstLine = true;
16359        int lastOomAdj = Integer.MIN_VALUE;
16360        long extraNativeRam = 0;
16361        long extraNativeMemtrack = 0;
16362        long cachedPss = 0;
16363        for (int i=0, N=memInfos.size(); i<N; i++) {
16364            ProcessMemInfo mi = memInfos.get(i);
16365
16366            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16367                cachedPss += mi.pss;
16368            }
16369
16370            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16371                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16372                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16373                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16374                if (lastOomAdj != mi.oomAdj) {
16375                    lastOomAdj = mi.oomAdj;
16376                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16377                        tag.append(" / ");
16378                    }
16379                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16380                        if (firstLine) {
16381                            stack.append(":");
16382                            firstLine = false;
16383                        }
16384                        stack.append("\n\t at ");
16385                    } else {
16386                        stack.append("$");
16387                    }
16388                } else {
16389                    tag.append(" ");
16390                    stack.append("$");
16391                }
16392                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16393                    appendMemBucket(tag, mi.pss, mi.name, false);
16394                }
16395                appendMemBucket(stack, mi.pss, mi.name, true);
16396                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16397                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16398                    stack.append("(");
16399                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16400                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16401                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16402                            stack.append(":");
16403                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16404                        }
16405                    }
16406                    stack.append(")");
16407                }
16408            }
16409
16410            appendMemInfo(fullNativeBuilder, mi);
16411            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16412                // The short form only has native processes that are >= 512K.
16413                if (mi.pss >= 512) {
16414                    appendMemInfo(shortNativeBuilder, mi);
16415                } else {
16416                    extraNativeRam += mi.pss;
16417                    extraNativeMemtrack += mi.memtrack;
16418                }
16419            } else {
16420                // Short form has all other details, but if we have collected RAM
16421                // from smaller native processes let's dump a summary of that.
16422                if (extraNativeRam > 0) {
16423                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16424                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16425                    shortNativeBuilder.append('\n');
16426                    extraNativeRam = 0;
16427                }
16428                appendMemInfo(fullJavaBuilder, mi);
16429            }
16430        }
16431
16432        fullJavaBuilder.append("           ");
16433        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16434        fullJavaBuilder.append(": TOTAL");
16435        if (totalMemtrack > 0) {
16436            fullJavaBuilder.append(" (");
16437            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16438            fullJavaBuilder.append(" memtrack)");
16439        } else {
16440        }
16441        fullJavaBuilder.append("\n");
16442
16443        MemInfoReader memInfo = new MemInfoReader();
16444        memInfo.readMemInfo();
16445        final long[] infos = memInfo.getRawInfo();
16446
16447        StringBuilder memInfoBuilder = new StringBuilder(1024);
16448        Debug.getMemInfo(infos);
16449        memInfoBuilder.append("  MemInfo: ");
16450        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16451        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16452        memInfoBuilder.append(stringifyKBSize(
16453                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16454        memInfoBuilder.append(stringifyKBSize(
16455                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16456        memInfoBuilder.append(stringifyKBSize(
16457                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16458        memInfoBuilder.append("           ");
16459        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16460        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16461        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16462        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16463        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16464            memInfoBuilder.append("  ZRAM: ");
16465            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16466            memInfoBuilder.append(" RAM, ");
16467            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16468            memInfoBuilder.append(" swap total, ");
16469            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16470            memInfoBuilder.append(" swap free\n");
16471        }
16472        final long[] ksm = getKsmInfo();
16473        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16474                || ksm[KSM_VOLATILE] != 0) {
16475            memInfoBuilder.append("  KSM: ");
16476            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16477            memInfoBuilder.append(" saved from shared ");
16478            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16479            memInfoBuilder.append("\n       ");
16480            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16481            memInfoBuilder.append(" unshared; ");
16482            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16483            memInfoBuilder.append(" volatile\n");
16484        }
16485        memInfoBuilder.append("  Free RAM: ");
16486        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16487                + memInfo.getFreeSizeKb()));
16488        memInfoBuilder.append("\n");
16489        memInfoBuilder.append("  Used RAM: ");
16490        memInfoBuilder.append(stringifyKBSize(
16491                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16492        memInfoBuilder.append("\n");
16493        memInfoBuilder.append("  Lost RAM: ");
16494        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16495                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16496                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16497        memInfoBuilder.append("\n");
16498        Slog.i(TAG, "Low on memory:");
16499        Slog.i(TAG, shortNativeBuilder.toString());
16500        Slog.i(TAG, fullJavaBuilder.toString());
16501        Slog.i(TAG, memInfoBuilder.toString());
16502
16503        StringBuilder dropBuilder = new StringBuilder(1024);
16504        /*
16505        StringWriter oomSw = new StringWriter();
16506        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16507        StringWriter catSw = new StringWriter();
16508        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16509        String[] emptyArgs = new String[] { };
16510        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16511        oomPw.flush();
16512        String oomString = oomSw.toString();
16513        */
16514        dropBuilder.append("Low on memory:");
16515        dropBuilder.append(stack);
16516        dropBuilder.append('\n');
16517        dropBuilder.append(fullNativeBuilder);
16518        dropBuilder.append(fullJavaBuilder);
16519        dropBuilder.append('\n');
16520        dropBuilder.append(memInfoBuilder);
16521        dropBuilder.append('\n');
16522        /*
16523        dropBuilder.append(oomString);
16524        dropBuilder.append('\n');
16525        */
16526        StringWriter catSw = new StringWriter();
16527        synchronized (ActivityManagerService.this) {
16528            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16529            String[] emptyArgs = new String[] { };
16530            catPw.println();
16531            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16532            catPw.println();
16533            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16534                    false, null).dumpLocked();
16535            catPw.println();
16536            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16537            catPw.flush();
16538        }
16539        dropBuilder.append(catSw.toString());
16540        addErrorToDropBox("lowmem", null, "system_server", null,
16541                null, tag.toString(), dropBuilder.toString(), null, null);
16542        //Slog.i(TAG, "Sent to dropbox:");
16543        //Slog.i(TAG, dropBuilder.toString());
16544        synchronized (ActivityManagerService.this) {
16545            long now = SystemClock.uptimeMillis();
16546            if (mLastMemUsageReportTime < now) {
16547                mLastMemUsageReportTime = now;
16548            }
16549        }
16550    }
16551
16552    /**
16553     * Searches array of arguments for the specified string
16554     * @param args array of argument strings
16555     * @param value value to search for
16556     * @return true if the value is contained in the array
16557     */
16558    private static boolean scanArgs(String[] args, String value) {
16559        if (args != null) {
16560            for (String arg : args) {
16561                if (value.equals(arg)) {
16562                    return true;
16563                }
16564            }
16565        }
16566        return false;
16567    }
16568
16569    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16570            ContentProviderRecord cpr, boolean always) {
16571        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16572
16573        if (!inLaunching || always) {
16574            synchronized (cpr) {
16575                cpr.launchingApp = null;
16576                cpr.notifyAll();
16577            }
16578            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16579            String names[] = cpr.info.authority.split(";");
16580            for (int j = 0; j < names.length; j++) {
16581                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16582            }
16583        }
16584
16585        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16586            ContentProviderConnection conn = cpr.connections.get(i);
16587            if (conn.waiting) {
16588                // If this connection is waiting for the provider, then we don't
16589                // need to mess with its process unless we are always removing
16590                // or for some reason the provider is not currently launching.
16591                if (inLaunching && !always) {
16592                    continue;
16593                }
16594            }
16595            ProcessRecord capp = conn.client;
16596            conn.dead = true;
16597            if (conn.stableCount > 0) {
16598                if (!capp.persistent && capp.thread != null
16599                        && capp.pid != 0
16600                        && capp.pid != MY_PID) {
16601                    capp.kill("depends on provider "
16602                            + cpr.name.flattenToShortString()
16603                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16604                }
16605            } else if (capp.thread != null && conn.provider.provider != null) {
16606                try {
16607                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16608                } catch (RemoteException e) {
16609                }
16610                // In the protocol here, we don't expect the client to correctly
16611                // clean up this connection, we'll just remove it.
16612                cpr.connections.remove(i);
16613                if (conn.client.conProviders.remove(conn)) {
16614                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16615                }
16616            }
16617        }
16618
16619        if (inLaunching && always) {
16620            mLaunchingProviders.remove(cpr);
16621        }
16622        return inLaunching;
16623    }
16624
16625    /**
16626     * Main code for cleaning up a process when it has gone away.  This is
16627     * called both as a result of the process dying, or directly when stopping
16628     * a process when running in single process mode.
16629     *
16630     * @return Returns true if the given process has been restarted, so the
16631     * app that was passed in must remain on the process lists.
16632     */
16633    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16634            boolean restarting, boolean allowRestart, int index) {
16635        if (index >= 0) {
16636            removeLruProcessLocked(app);
16637            ProcessList.remove(app.pid);
16638        }
16639
16640        mProcessesToGc.remove(app);
16641        mPendingPssProcesses.remove(app);
16642
16643        // Dismiss any open dialogs.
16644        if (app.crashDialog != null && !app.forceCrashReport) {
16645            app.crashDialog.dismiss();
16646            app.crashDialog = null;
16647        }
16648        if (app.anrDialog != null) {
16649            app.anrDialog.dismiss();
16650            app.anrDialog = null;
16651        }
16652        if (app.waitDialog != null) {
16653            app.waitDialog.dismiss();
16654            app.waitDialog = null;
16655        }
16656
16657        app.crashing = false;
16658        app.notResponding = false;
16659
16660        app.resetPackageList(mProcessStats);
16661        app.unlinkDeathRecipient();
16662        app.makeInactive(mProcessStats);
16663        app.waitingToKill = null;
16664        app.forcingToForeground = null;
16665        updateProcessForegroundLocked(app, false, false);
16666        app.foregroundActivities = false;
16667        app.hasShownUi = false;
16668        app.treatLikeActivity = false;
16669        app.hasAboveClient = false;
16670        app.hasClientActivities = false;
16671
16672        mServices.killServicesLocked(app, allowRestart);
16673
16674        boolean restart = false;
16675
16676        // Remove published content providers.
16677        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16678            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16679            final boolean always = app.bad || !allowRestart;
16680            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16681            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16682                // We left the provider in the launching list, need to
16683                // restart it.
16684                restart = true;
16685            }
16686
16687            cpr.provider = null;
16688            cpr.proc = null;
16689        }
16690        app.pubProviders.clear();
16691
16692        // Take care of any launching providers waiting for this process.
16693        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16694            restart = true;
16695        }
16696
16697        // Unregister from connected content providers.
16698        if (!app.conProviders.isEmpty()) {
16699            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16700                ContentProviderConnection conn = app.conProviders.get(i);
16701                conn.provider.connections.remove(conn);
16702                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16703                        conn.provider.name);
16704            }
16705            app.conProviders.clear();
16706        }
16707
16708        // At this point there may be remaining entries in mLaunchingProviders
16709        // where we were the only one waiting, so they are no longer of use.
16710        // Look for these and clean up if found.
16711        // XXX Commented out for now.  Trying to figure out a way to reproduce
16712        // the actual situation to identify what is actually going on.
16713        if (false) {
16714            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16715                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16716                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16717                    synchronized (cpr) {
16718                        cpr.launchingApp = null;
16719                        cpr.notifyAll();
16720                    }
16721                }
16722            }
16723        }
16724
16725        skipCurrentReceiverLocked(app);
16726
16727        // Unregister any receivers.
16728        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16729            removeReceiverLocked(app.receivers.valueAt(i));
16730        }
16731        app.receivers.clear();
16732
16733        // If the app is undergoing backup, tell the backup manager about it
16734        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16735            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16736                    + mBackupTarget.appInfo + " died during backup");
16737            try {
16738                IBackupManager bm = IBackupManager.Stub.asInterface(
16739                        ServiceManager.getService(Context.BACKUP_SERVICE));
16740                bm.agentDisconnected(app.info.packageName);
16741            } catch (RemoteException e) {
16742                // can't happen; backup manager is local
16743            }
16744        }
16745
16746        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16747            ProcessChangeItem item = mPendingProcessChanges.get(i);
16748            if (item.pid == app.pid) {
16749                mPendingProcessChanges.remove(i);
16750                mAvailProcessChanges.add(item);
16751            }
16752        }
16753        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16754                null).sendToTarget();
16755
16756        // If the caller is restarting this app, then leave it in its
16757        // current lists and let the caller take care of it.
16758        if (restarting) {
16759            return false;
16760        }
16761
16762        if (!app.persistent || app.isolated) {
16763            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16764                    "Removing non-persistent process during cleanup: " + app);
16765            removeProcessNameLocked(app.processName, app.uid);
16766            if (mHeavyWeightProcess == app) {
16767                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16768                        mHeavyWeightProcess.userId, 0));
16769                mHeavyWeightProcess = null;
16770            }
16771        } else if (!app.removed) {
16772            // This app is persistent, so we need to keep its record around.
16773            // If it is not already on the pending app list, add it there
16774            // and start a new process for it.
16775            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16776                mPersistentStartingProcesses.add(app);
16777                restart = true;
16778            }
16779        }
16780        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16781                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16782        mProcessesOnHold.remove(app);
16783
16784        if (app == mHomeProcess) {
16785            mHomeProcess = null;
16786        }
16787        if (app == mPreviousProcess) {
16788            mPreviousProcess = null;
16789        }
16790
16791        if (restart && !app.isolated) {
16792            // We have components that still need to be running in the
16793            // process, so re-launch it.
16794            if (index < 0) {
16795                ProcessList.remove(app.pid);
16796            }
16797            addProcessNameLocked(app);
16798            startProcessLocked(app, "restart", app.processName);
16799            return true;
16800        } else if (app.pid > 0 && app.pid != MY_PID) {
16801            // Goodbye!
16802            boolean removed;
16803            synchronized (mPidsSelfLocked) {
16804                mPidsSelfLocked.remove(app.pid);
16805                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16806            }
16807            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16808            if (app.isolated) {
16809                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16810            }
16811            app.setPid(0);
16812        }
16813        return false;
16814    }
16815
16816    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16817        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16818            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16819            if (cpr.launchingApp == app) {
16820                return true;
16821            }
16822        }
16823        return false;
16824    }
16825
16826    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16827        // Look through the content providers we are waiting to have launched,
16828        // and if any run in this process then either schedule a restart of
16829        // the process or kill the client waiting for it if this process has
16830        // gone bad.
16831        boolean restart = false;
16832        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16833            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16834            if (cpr.launchingApp == app) {
16835                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16836                    restart = true;
16837                } else {
16838                    removeDyingProviderLocked(app, cpr, true);
16839                }
16840            }
16841        }
16842        return restart;
16843    }
16844
16845    // =========================================================
16846    // SERVICES
16847    // =========================================================
16848
16849    @Override
16850    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16851            int flags) {
16852        enforceNotIsolatedCaller("getServices");
16853        synchronized (this) {
16854            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16855        }
16856    }
16857
16858    @Override
16859    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16860        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16861        synchronized (this) {
16862            return mServices.getRunningServiceControlPanelLocked(name);
16863        }
16864    }
16865
16866    @Override
16867    public ComponentName startService(IApplicationThread caller, Intent service,
16868            String resolvedType, String callingPackage, int userId)
16869            throws TransactionTooLargeException {
16870        enforceNotIsolatedCaller("startService");
16871        // Refuse possible leaked file descriptors
16872        if (service != null && service.hasFileDescriptors() == true) {
16873            throw new IllegalArgumentException("File descriptors passed in Intent");
16874        }
16875
16876        if (callingPackage == null) {
16877            throw new IllegalArgumentException("callingPackage cannot be null");
16878        }
16879
16880        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16881                "startService: " + service + " type=" + resolvedType);
16882        synchronized(this) {
16883            final int callingPid = Binder.getCallingPid();
16884            final int callingUid = Binder.getCallingUid();
16885            final long origId = Binder.clearCallingIdentity();
16886            ComponentName res = mServices.startServiceLocked(caller, service,
16887                    resolvedType, callingPid, callingUid, callingPackage, userId);
16888            Binder.restoreCallingIdentity(origId);
16889            return res;
16890        }
16891    }
16892
16893    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16894            String callingPackage, int userId)
16895            throws TransactionTooLargeException {
16896        synchronized(this) {
16897            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16898                    "startServiceInPackage: " + service + " type=" + resolvedType);
16899            final long origId = Binder.clearCallingIdentity();
16900            ComponentName res = mServices.startServiceLocked(null, service,
16901                    resolvedType, -1, uid, callingPackage, userId);
16902            Binder.restoreCallingIdentity(origId);
16903            return res;
16904        }
16905    }
16906
16907    @Override
16908    public int stopService(IApplicationThread caller, Intent service,
16909            String resolvedType, int userId) {
16910        enforceNotIsolatedCaller("stopService");
16911        // Refuse possible leaked file descriptors
16912        if (service != null && service.hasFileDescriptors() == true) {
16913            throw new IllegalArgumentException("File descriptors passed in Intent");
16914        }
16915
16916        synchronized(this) {
16917            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16918        }
16919    }
16920
16921    @Override
16922    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16923        enforceNotIsolatedCaller("peekService");
16924        // Refuse possible leaked file descriptors
16925        if (service != null && service.hasFileDescriptors() == true) {
16926            throw new IllegalArgumentException("File descriptors passed in Intent");
16927        }
16928
16929        if (callingPackage == null) {
16930            throw new IllegalArgumentException("callingPackage cannot be null");
16931        }
16932
16933        synchronized(this) {
16934            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16935        }
16936    }
16937
16938    @Override
16939    public boolean stopServiceToken(ComponentName className, IBinder token,
16940            int startId) {
16941        synchronized(this) {
16942            return mServices.stopServiceTokenLocked(className, token, startId);
16943        }
16944    }
16945
16946    @Override
16947    public void setServiceForeground(ComponentName className, IBinder token,
16948            int id, Notification notification, int flags) {
16949        synchronized(this) {
16950            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16951        }
16952    }
16953
16954    @Override
16955    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16956            boolean requireFull, String name, String callerPackage) {
16957        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16958                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16959    }
16960
16961    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16962            String className, int flags) {
16963        boolean result = false;
16964        // For apps that don't have pre-defined UIDs, check for permission
16965        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16966            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16967                if (ActivityManager.checkUidPermission(
16968                        INTERACT_ACROSS_USERS,
16969                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16970                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16971                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16972                            + " requests FLAG_SINGLE_USER, but app does not hold "
16973                            + INTERACT_ACROSS_USERS;
16974                    Slog.w(TAG, msg);
16975                    throw new SecurityException(msg);
16976                }
16977                // Permission passed
16978                result = true;
16979            }
16980        } else if ("system".equals(componentProcessName)) {
16981            result = true;
16982        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16983            // Phone app and persistent apps are allowed to export singleuser providers.
16984            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16985                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16986        }
16987        if (DEBUG_MU) Slog.v(TAG_MU,
16988                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16989                + Integer.toHexString(flags) + ") = " + result);
16990        return result;
16991    }
16992
16993    /**
16994     * Checks to see if the caller is in the same app as the singleton
16995     * component, or the component is in a special app. It allows special apps
16996     * to export singleton components but prevents exporting singleton
16997     * components for regular apps.
16998     */
16999    boolean isValidSingletonCall(int callingUid, int componentUid) {
17000        int componentAppId = UserHandle.getAppId(componentUid);
17001        return UserHandle.isSameApp(callingUid, componentUid)
17002                || componentAppId == Process.SYSTEM_UID
17003                || componentAppId == Process.PHONE_UID
17004                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17005                        == PackageManager.PERMISSION_GRANTED;
17006    }
17007
17008    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17009            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17010            int userId) throws TransactionTooLargeException {
17011        enforceNotIsolatedCaller("bindService");
17012
17013        // Refuse possible leaked file descriptors
17014        if (service != null && service.hasFileDescriptors() == true) {
17015            throw new IllegalArgumentException("File descriptors passed in Intent");
17016        }
17017
17018        if (callingPackage == null) {
17019            throw new IllegalArgumentException("callingPackage cannot be null");
17020        }
17021
17022        synchronized(this) {
17023            return mServices.bindServiceLocked(caller, token, service,
17024                    resolvedType, connection, flags, callingPackage, userId);
17025        }
17026    }
17027
17028    public boolean unbindService(IServiceConnection connection) {
17029        synchronized (this) {
17030            return mServices.unbindServiceLocked(connection);
17031        }
17032    }
17033
17034    public void publishService(IBinder token, Intent intent, IBinder service) {
17035        // Refuse possible leaked file descriptors
17036        if (intent != null && intent.hasFileDescriptors() == true) {
17037            throw new IllegalArgumentException("File descriptors passed in Intent");
17038        }
17039
17040        synchronized(this) {
17041            if (!(token instanceof ServiceRecord)) {
17042                throw new IllegalArgumentException("Invalid service token");
17043            }
17044            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17045        }
17046    }
17047
17048    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17049        // Refuse possible leaked file descriptors
17050        if (intent != null && intent.hasFileDescriptors() == true) {
17051            throw new IllegalArgumentException("File descriptors passed in Intent");
17052        }
17053
17054        synchronized(this) {
17055            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17056        }
17057    }
17058
17059    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17060        synchronized(this) {
17061            if (!(token instanceof ServiceRecord)) {
17062                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17063                throw new IllegalArgumentException("Invalid service token");
17064            }
17065            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17066        }
17067    }
17068
17069    // =========================================================
17070    // BACKUP AND RESTORE
17071    // =========================================================
17072
17073    // Cause the target app to be launched if necessary and its backup agent
17074    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17075    // activity manager to announce its creation.
17076    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17077        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17078        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17079
17080        IPackageManager pm = AppGlobals.getPackageManager();
17081        ApplicationInfo app = null;
17082        try {
17083            app = pm.getApplicationInfo(packageName, 0, userId);
17084        } catch (RemoteException e) {
17085            // can't happen; package manager is process-local
17086        }
17087        if (app == null) {
17088            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17089            return false;
17090        }
17091
17092        synchronized(this) {
17093            // !!! TODO: currently no check here that we're already bound
17094            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17095            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17096            synchronized (stats) {
17097                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17098            }
17099
17100            // Backup agent is now in use, its package can't be stopped.
17101            try {
17102                AppGlobals.getPackageManager().setPackageStoppedState(
17103                        app.packageName, false, UserHandle.getUserId(app.uid));
17104            } catch (RemoteException e) {
17105            } catch (IllegalArgumentException e) {
17106                Slog.w(TAG, "Failed trying to unstop package "
17107                        + app.packageName + ": " + e);
17108            }
17109
17110            BackupRecord r = new BackupRecord(ss, app, backupMode);
17111            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17112                    ? new ComponentName(app.packageName, app.backupAgentName)
17113                    : new ComponentName("android", "FullBackupAgent");
17114            // startProcessLocked() returns existing proc's record if it's already running
17115            ProcessRecord proc = startProcessLocked(app.processName, app,
17116                    false, 0, "backup", hostingName, false, false, false);
17117            if (proc == null) {
17118                Slog.e(TAG, "Unable to start backup agent process " + r);
17119                return false;
17120            }
17121
17122            // If the app is a regular app (uid >= 10000) and not the system server or phone
17123            // process, etc, then mark it as being in full backup so that certain calls to the
17124            // process can be blocked. This is not reset to false anywhere because we kill the
17125            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17126            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17127                proc.inFullBackup = true;
17128            }
17129            r.app = proc;
17130            mBackupTarget = r;
17131            mBackupAppName = app.packageName;
17132
17133            // Try not to kill the process during backup
17134            updateOomAdjLocked(proc);
17135
17136            // If the process is already attached, schedule the creation of the backup agent now.
17137            // If it is not yet live, this will be done when it attaches to the framework.
17138            if (proc.thread != null) {
17139                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17140                try {
17141                    proc.thread.scheduleCreateBackupAgent(app,
17142                            compatibilityInfoForPackageLocked(app), backupMode);
17143                } catch (RemoteException e) {
17144                    // Will time out on the backup manager side
17145                }
17146            } else {
17147                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17148            }
17149            // Invariants: at this point, the target app process exists and the application
17150            // is either already running or in the process of coming up.  mBackupTarget and
17151            // mBackupAppName describe the app, so that when it binds back to the AM we
17152            // know that it's scheduled for a backup-agent operation.
17153        }
17154
17155        return true;
17156    }
17157
17158    @Override
17159    public void clearPendingBackup() {
17160        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17161        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17162
17163        synchronized (this) {
17164            mBackupTarget = null;
17165            mBackupAppName = null;
17166        }
17167    }
17168
17169    // A backup agent has just come up
17170    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17171        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17172                + " = " + agent);
17173
17174        synchronized(this) {
17175            if (!agentPackageName.equals(mBackupAppName)) {
17176                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17177                return;
17178            }
17179        }
17180
17181        long oldIdent = Binder.clearCallingIdentity();
17182        try {
17183            IBackupManager bm = IBackupManager.Stub.asInterface(
17184                    ServiceManager.getService(Context.BACKUP_SERVICE));
17185            bm.agentConnected(agentPackageName, agent);
17186        } catch (RemoteException e) {
17187            // can't happen; the backup manager service is local
17188        } catch (Exception e) {
17189            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17190            e.printStackTrace();
17191        } finally {
17192            Binder.restoreCallingIdentity(oldIdent);
17193        }
17194    }
17195
17196    // done with this agent
17197    public void unbindBackupAgent(ApplicationInfo appInfo) {
17198        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17199        if (appInfo == null) {
17200            Slog.w(TAG, "unbind backup agent for null app");
17201            return;
17202        }
17203
17204        synchronized(this) {
17205            try {
17206                if (mBackupAppName == null) {
17207                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17208                    return;
17209                }
17210
17211                if (!mBackupAppName.equals(appInfo.packageName)) {
17212                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17213                    return;
17214                }
17215
17216                // Not backing this app up any more; reset its OOM adjustment
17217                final ProcessRecord proc = mBackupTarget.app;
17218                updateOomAdjLocked(proc);
17219
17220                // If the app crashed during backup, 'thread' will be null here
17221                if (proc.thread != null) {
17222                    try {
17223                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17224                                compatibilityInfoForPackageLocked(appInfo));
17225                    } catch (Exception e) {
17226                        Slog.e(TAG, "Exception when unbinding backup agent:");
17227                        e.printStackTrace();
17228                    }
17229                }
17230            } finally {
17231                mBackupTarget = null;
17232                mBackupAppName = null;
17233            }
17234        }
17235    }
17236    // =========================================================
17237    // BROADCASTS
17238    // =========================================================
17239
17240    boolean isPendingBroadcastProcessLocked(int pid) {
17241        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17242                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17243    }
17244
17245    void skipPendingBroadcastLocked(int pid) {
17246            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17247            for (BroadcastQueue queue : mBroadcastQueues) {
17248                queue.skipPendingBroadcastLocked(pid);
17249            }
17250    }
17251
17252    // The app just attached; send any pending broadcasts that it should receive
17253    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17254        boolean didSomething = false;
17255        for (BroadcastQueue queue : mBroadcastQueues) {
17256            didSomething |= queue.sendPendingBroadcastsLocked(app);
17257        }
17258        return didSomething;
17259    }
17260
17261    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17262            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17263        enforceNotIsolatedCaller("registerReceiver");
17264        ArrayList<Intent> stickyIntents = null;
17265        ProcessRecord callerApp = null;
17266        int callingUid;
17267        int callingPid;
17268        synchronized(this) {
17269            if (caller != null) {
17270                callerApp = getRecordForAppLocked(caller);
17271                if (callerApp == null) {
17272                    throw new SecurityException(
17273                            "Unable to find app for caller " + caller
17274                            + " (pid=" + Binder.getCallingPid()
17275                            + ") when registering receiver " + receiver);
17276                }
17277                if (callerApp.info.uid != Process.SYSTEM_UID &&
17278                        !callerApp.pkgList.containsKey(callerPackage) &&
17279                        !"android".equals(callerPackage)) {
17280                    throw new SecurityException("Given caller package " + callerPackage
17281                            + " is not running in process " + callerApp);
17282                }
17283                callingUid = callerApp.info.uid;
17284                callingPid = callerApp.pid;
17285            } else {
17286                callerPackage = null;
17287                callingUid = Binder.getCallingUid();
17288                callingPid = Binder.getCallingPid();
17289            }
17290
17291            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17292                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17293
17294            Iterator<String> actions = filter.actionsIterator();
17295            if (actions == null) {
17296                ArrayList<String> noAction = new ArrayList<String>(1);
17297                noAction.add(null);
17298                actions = noAction.iterator();
17299            }
17300
17301            // Collect stickies of users
17302            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17303            while (actions.hasNext()) {
17304                String action = actions.next();
17305                for (int id : userIds) {
17306                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17307                    if (stickies != null) {
17308                        ArrayList<Intent> intents = stickies.get(action);
17309                        if (intents != null) {
17310                            if (stickyIntents == null) {
17311                                stickyIntents = new ArrayList<Intent>();
17312                            }
17313                            stickyIntents.addAll(intents);
17314                        }
17315                    }
17316                }
17317            }
17318        }
17319
17320        ArrayList<Intent> allSticky = null;
17321        if (stickyIntents != null) {
17322            final ContentResolver resolver = mContext.getContentResolver();
17323            // Look for any matching sticky broadcasts...
17324            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17325                Intent intent = stickyIntents.get(i);
17326                // If intent has scheme "content", it will need to acccess
17327                // provider that needs to lock mProviderMap in ActivityThread
17328                // and also it may need to wait application response, so we
17329                // cannot lock ActivityManagerService here.
17330                if (filter.match(resolver, intent, true, TAG) >= 0) {
17331                    if (allSticky == null) {
17332                        allSticky = new ArrayList<Intent>();
17333                    }
17334                    allSticky.add(intent);
17335                }
17336            }
17337        }
17338
17339        // The first sticky in the list is returned directly back to the client.
17340        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17341        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17342        if (receiver == null) {
17343            return sticky;
17344        }
17345
17346        synchronized (this) {
17347            if (callerApp != null && (callerApp.thread == null
17348                    || callerApp.thread.asBinder() != caller.asBinder())) {
17349                // Original caller already died
17350                return null;
17351            }
17352            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17353            if (rl == null) {
17354                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17355                        userId, receiver);
17356                if (rl.app != null) {
17357                    rl.app.receivers.add(rl);
17358                } else {
17359                    try {
17360                        receiver.asBinder().linkToDeath(rl, 0);
17361                    } catch (RemoteException e) {
17362                        return sticky;
17363                    }
17364                    rl.linkedToDeath = true;
17365                }
17366                mRegisteredReceivers.put(receiver.asBinder(), rl);
17367            } else if (rl.uid != callingUid) {
17368                throw new IllegalArgumentException(
17369                        "Receiver requested to register for uid " + callingUid
17370                        + " was previously registered for uid " + rl.uid);
17371            } else if (rl.pid != callingPid) {
17372                throw new IllegalArgumentException(
17373                        "Receiver requested to register for pid " + callingPid
17374                        + " was previously registered for pid " + rl.pid);
17375            } else if (rl.userId != userId) {
17376                throw new IllegalArgumentException(
17377                        "Receiver requested to register for user " + userId
17378                        + " was previously registered for user " + rl.userId);
17379            }
17380            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17381                    permission, callingUid, userId);
17382            rl.add(bf);
17383            if (!bf.debugCheck()) {
17384                Slog.w(TAG, "==> For Dynamic broadcast");
17385            }
17386            mReceiverResolver.addFilter(bf);
17387
17388            // Enqueue broadcasts for all existing stickies that match
17389            // this filter.
17390            if (allSticky != null) {
17391                ArrayList receivers = new ArrayList();
17392                receivers.add(bf);
17393
17394                final int stickyCount = allSticky.size();
17395                for (int i = 0; i < stickyCount; i++) {
17396                    Intent intent = allSticky.get(i);
17397                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17398                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17399                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17400                            null, 0, null, null, false, true, true, -1);
17401                    queue.enqueueParallelBroadcastLocked(r);
17402                    queue.scheduleBroadcastsLocked();
17403                }
17404            }
17405
17406            return sticky;
17407        }
17408    }
17409
17410    public void unregisterReceiver(IIntentReceiver receiver) {
17411        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17412
17413        final long origId = Binder.clearCallingIdentity();
17414        try {
17415            boolean doTrim = false;
17416
17417            synchronized(this) {
17418                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17419                if (rl != null) {
17420                    final BroadcastRecord r = rl.curBroadcast;
17421                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17422                        final boolean doNext = r.queue.finishReceiverLocked(
17423                                r, r.resultCode, r.resultData, r.resultExtras,
17424                                r.resultAbort, false);
17425                        if (doNext) {
17426                            doTrim = true;
17427                            r.queue.processNextBroadcast(false);
17428                        }
17429                    }
17430
17431                    if (rl.app != null) {
17432                        rl.app.receivers.remove(rl);
17433                    }
17434                    removeReceiverLocked(rl);
17435                    if (rl.linkedToDeath) {
17436                        rl.linkedToDeath = false;
17437                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17438                    }
17439                }
17440            }
17441
17442            // If we actually concluded any broadcasts, we might now be able
17443            // to trim the recipients' apps from our working set
17444            if (doTrim) {
17445                trimApplications();
17446                return;
17447            }
17448
17449        } finally {
17450            Binder.restoreCallingIdentity(origId);
17451        }
17452    }
17453
17454    void removeReceiverLocked(ReceiverList rl) {
17455        mRegisteredReceivers.remove(rl.receiver.asBinder());
17456        for (int i = rl.size() - 1; i >= 0; i--) {
17457            mReceiverResolver.removeFilter(rl.get(i));
17458        }
17459    }
17460
17461    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17462        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17463            ProcessRecord r = mLruProcesses.get(i);
17464            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17465                try {
17466                    r.thread.dispatchPackageBroadcast(cmd, packages);
17467                } catch (RemoteException ex) {
17468                }
17469            }
17470        }
17471    }
17472
17473    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17474            int callingUid, int[] users) {
17475        // TODO: come back and remove this assumption to triage all broadcasts
17476        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17477
17478        List<ResolveInfo> receivers = null;
17479        try {
17480            HashSet<ComponentName> singleUserReceivers = null;
17481            boolean scannedFirstReceivers = false;
17482            for (int user : users) {
17483                // Skip users that have Shell restrictions, with exception of always permitted
17484                // Shell broadcasts
17485                if (callingUid == Process.SHELL_UID
17486                        && mUserController.hasUserRestriction(
17487                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17488                        && !isPermittedShellBroadcast(intent)) {
17489                    continue;
17490                }
17491                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17492                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17493                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17494                    // If this is not the system user, we need to check for
17495                    // any receivers that should be filtered out.
17496                    for (int i=0; i<newReceivers.size(); i++) {
17497                        ResolveInfo ri = newReceivers.get(i);
17498                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17499                            newReceivers.remove(i);
17500                            i--;
17501                        }
17502                    }
17503                }
17504                if (newReceivers != null && newReceivers.size() == 0) {
17505                    newReceivers = null;
17506                }
17507                if (receivers == null) {
17508                    receivers = newReceivers;
17509                } else if (newReceivers != null) {
17510                    // We need to concatenate the additional receivers
17511                    // found with what we have do far.  This would be easy,
17512                    // but we also need to de-dup any receivers that are
17513                    // singleUser.
17514                    if (!scannedFirstReceivers) {
17515                        // Collect any single user receivers we had already retrieved.
17516                        scannedFirstReceivers = true;
17517                        for (int i=0; i<receivers.size(); i++) {
17518                            ResolveInfo ri = receivers.get(i);
17519                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17520                                ComponentName cn = new ComponentName(
17521                                        ri.activityInfo.packageName, ri.activityInfo.name);
17522                                if (singleUserReceivers == null) {
17523                                    singleUserReceivers = new HashSet<ComponentName>();
17524                                }
17525                                singleUserReceivers.add(cn);
17526                            }
17527                        }
17528                    }
17529                    // Add the new results to the existing results, tracking
17530                    // and de-dupping single user receivers.
17531                    for (int i=0; i<newReceivers.size(); i++) {
17532                        ResolveInfo ri = newReceivers.get(i);
17533                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17534                            ComponentName cn = new ComponentName(
17535                                    ri.activityInfo.packageName, ri.activityInfo.name);
17536                            if (singleUserReceivers == null) {
17537                                singleUserReceivers = new HashSet<ComponentName>();
17538                            }
17539                            if (!singleUserReceivers.contains(cn)) {
17540                                singleUserReceivers.add(cn);
17541                                receivers.add(ri);
17542                            }
17543                        } else {
17544                            receivers.add(ri);
17545                        }
17546                    }
17547                }
17548            }
17549        } catch (RemoteException ex) {
17550            // pm is in same process, this will never happen.
17551        }
17552        return receivers;
17553    }
17554
17555    private boolean isPermittedShellBroadcast(Intent intent) {
17556        // remote bugreport should always be allowed to be taken
17557        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17558    }
17559
17560    final int broadcastIntentLocked(ProcessRecord callerApp,
17561            String callerPackage, Intent intent, String resolvedType,
17562            IIntentReceiver resultTo, int resultCode, String resultData,
17563            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17564            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17565        intent = new Intent(intent);
17566
17567        // By default broadcasts do not go to stopped apps.
17568        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17569
17570        // If we have not finished booting, don't allow this to launch new processes.
17571        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17572            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17573        }
17574
17575        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17576                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17577                + " ordered=" + ordered + " userid=" + userId);
17578        if ((resultTo != null) && !ordered) {
17579            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17580        }
17581
17582        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17583                ALLOW_NON_FULL, "broadcast", callerPackage);
17584
17585        // Make sure that the user who is receiving this broadcast is running.
17586        // If not, we will just skip it. Make an exception for shutdown broadcasts
17587        // and upgrade steps.
17588
17589        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17590            if ((callingUid != Process.SYSTEM_UID
17591                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17592                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17593                Slog.w(TAG, "Skipping broadcast of " + intent
17594                        + ": user " + userId + " is stopped");
17595                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17596            }
17597        }
17598
17599        BroadcastOptions brOptions = null;
17600        if (bOptions != null) {
17601            brOptions = new BroadcastOptions(bOptions);
17602            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17603                // See if the caller is allowed to do this.  Note we are checking against
17604                // the actual real caller (not whoever provided the operation as say a
17605                // PendingIntent), because that who is actually supplied the arguments.
17606                if (checkComponentPermission(
17607                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17608                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17609                        != PackageManager.PERMISSION_GRANTED) {
17610                    String msg = "Permission Denial: " + intent.getAction()
17611                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17612                            + ", uid=" + callingUid + ")"
17613                            + " requires "
17614                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17615                    Slog.w(TAG, msg);
17616                    throw new SecurityException(msg);
17617                }
17618            }
17619        }
17620
17621        // Verify that protected broadcasts are only being sent by system code,
17622        // and that system code is only sending protected broadcasts.
17623        final String action = intent.getAction();
17624        final boolean isProtectedBroadcast;
17625        try {
17626            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17627        } catch (RemoteException e) {
17628            Slog.w(TAG, "Remote exception", e);
17629            return ActivityManager.BROADCAST_SUCCESS;
17630        }
17631
17632        final boolean isCallerSystem;
17633        switch (UserHandle.getAppId(callingUid)) {
17634            case Process.ROOT_UID:
17635            case Process.SYSTEM_UID:
17636            case Process.PHONE_UID:
17637            case Process.BLUETOOTH_UID:
17638            case Process.NFC_UID:
17639                isCallerSystem = true;
17640                break;
17641            default:
17642                isCallerSystem = (callerApp != null) && callerApp.persistent;
17643                break;
17644        }
17645
17646        if (isCallerSystem) {
17647            if (isProtectedBroadcast
17648                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17649                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17650                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17651                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17652                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17653                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17654                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17655                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17656                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17657                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17658                // Broadcast is either protected, or it's a public action that
17659                // we've relaxed, so it's fine for system internals to send.
17660            } else {
17661                // The vast majority of broadcasts sent from system internals
17662                // should be protected to avoid security holes, so yell loudly
17663                // to ensure we examine these cases.
17664                if (callerApp != null) {
17665                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17666                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17667                            new Throwable());
17668                } else {
17669                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17670                            + " from system uid " + UserHandle.formatUid(callingUid)
17671                            + " pkg " + callerPackage,
17672                            new Throwable());
17673                }
17674            }
17675
17676        } else {
17677            if (isProtectedBroadcast) {
17678                String msg = "Permission Denial: not allowed to send broadcast "
17679                        + action + " from pid="
17680                        + callingPid + ", uid=" + callingUid;
17681                Slog.w(TAG, msg);
17682                throw new SecurityException(msg);
17683
17684            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17685                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17686                // Special case for compatibility: we don't want apps to send this,
17687                // but historically it has not been protected and apps may be using it
17688                // to poke their own app widget.  So, instead of making it protected,
17689                // just limit it to the caller.
17690                if (callerPackage == null) {
17691                    String msg = "Permission Denial: not allowed to send broadcast "
17692                            + action + " from unknown caller.";
17693                    Slog.w(TAG, msg);
17694                    throw new SecurityException(msg);
17695                } else if (intent.getComponent() != null) {
17696                    // They are good enough to send to an explicit component...  verify
17697                    // it is being sent to the calling app.
17698                    if (!intent.getComponent().getPackageName().equals(
17699                            callerPackage)) {
17700                        String msg = "Permission Denial: not allowed to send broadcast "
17701                                + action + " to "
17702                                + intent.getComponent().getPackageName() + " from "
17703                                + callerPackage;
17704                        Slog.w(TAG, msg);
17705                        throw new SecurityException(msg);
17706                    }
17707                } else {
17708                    // Limit broadcast to their own package.
17709                    intent.setPackage(callerPackage);
17710                }
17711            }
17712        }
17713
17714        if (action != null) {
17715            switch (action) {
17716                case Intent.ACTION_UID_REMOVED:
17717                case Intent.ACTION_PACKAGE_REMOVED:
17718                case Intent.ACTION_PACKAGE_CHANGED:
17719                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17720                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17721                case Intent.ACTION_PACKAGES_SUSPENDED:
17722                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17723                    // Handle special intents: if this broadcast is from the package
17724                    // manager about a package being removed, we need to remove all of
17725                    // its activities from the history stack.
17726                    if (checkComponentPermission(
17727                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17728                            callingPid, callingUid, -1, true)
17729                            != PackageManager.PERMISSION_GRANTED) {
17730                        String msg = "Permission Denial: " + intent.getAction()
17731                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17732                                + ", uid=" + callingUid + ")"
17733                                + " requires "
17734                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17735                        Slog.w(TAG, msg);
17736                        throw new SecurityException(msg);
17737                    }
17738                    switch (action) {
17739                        case Intent.ACTION_UID_REMOVED:
17740                            final Bundle intentExtras = intent.getExtras();
17741                            final int uid = intentExtras != null
17742                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17743                            if (uid >= 0) {
17744                                mBatteryStatsService.removeUid(uid);
17745                                mAppOpsService.uidRemoved(uid);
17746                            }
17747                            break;
17748                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17749                            // If resources are unavailable just force stop all those packages
17750                            // and flush the attribute cache as well.
17751                            String list[] =
17752                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17753                            if (list != null && list.length > 0) {
17754                                for (int i = 0; i < list.length; i++) {
17755                                    forceStopPackageLocked(list[i], -1, false, true, true,
17756                                            false, false, userId, "storage unmount");
17757                                }
17758                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17759                                sendPackageBroadcastLocked(
17760                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17761                                        userId);
17762                            }
17763                            break;
17764                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17765                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17766                            break;
17767                        case Intent.ACTION_PACKAGE_REMOVED:
17768                        case Intent.ACTION_PACKAGE_CHANGED:
17769                            Uri data = intent.getData();
17770                            String ssp;
17771                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17772                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17773                                final boolean replacing =
17774                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17775                                final boolean killProcess =
17776                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17777                                final boolean fullUninstall = removed && !replacing;
17778                                if (removed) {
17779                                    if (killProcess) {
17780                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17781                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17782                                                false, true, true, false, fullUninstall, userId,
17783                                                removed ? "pkg removed" : "pkg changed");
17784                                    }
17785                                    final int cmd = killProcess
17786                                            ? IApplicationThread.PACKAGE_REMOVED
17787                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17788                                    sendPackageBroadcastLocked(cmd,
17789                                            new String[] {ssp}, userId);
17790                                    if (fullUninstall) {
17791                                        mAppOpsService.packageRemoved(
17792                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17793
17794                                        // Remove all permissions granted from/to this package
17795                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17796
17797                                        removeTasksByPackageNameLocked(ssp, userId);
17798
17799                                        // Hide the "unsupported display" dialog if necessary.
17800                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17801                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17802                                            mUnsupportedDisplaySizeDialog.dismiss();
17803                                            mUnsupportedDisplaySizeDialog = null;
17804                                        }
17805                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17806                                        mBatteryStatsService.notePackageUninstalled(ssp);
17807                                    }
17808                                } else {
17809                                    if (killProcess) {
17810                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17811                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17812                                                userId, ProcessList.INVALID_ADJ,
17813                                                false, true, true, false, "change " + ssp);
17814                                    }
17815                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17816                                            intent.getStringArrayExtra(
17817                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17818                                }
17819                            }
17820                            break;
17821                        case Intent.ACTION_PACKAGES_SUSPENDED:
17822                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17823                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17824                                    intent.getAction());
17825                            final String[] packageNames = intent.getStringArrayExtra(
17826                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17827                            final int userHandle = intent.getIntExtra(
17828                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17829
17830                            synchronized(ActivityManagerService.this) {
17831                                mRecentTasks.onPackagesSuspendedChanged(
17832                                        packageNames, suspended, userHandle);
17833                            }
17834                            break;
17835                    }
17836                    break;
17837                case Intent.ACTION_PACKAGE_REPLACED:
17838                {
17839                    final Uri data = intent.getData();
17840                    final String ssp;
17841                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17842                        final ApplicationInfo aInfo =
17843                                getPackageManagerInternalLocked().getApplicationInfo(
17844                                        ssp,
17845                                        userId);
17846                        if (aInfo == null) {
17847                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17848                                    + " ssp=" + ssp + " data=" + data);
17849                            return ActivityManager.BROADCAST_SUCCESS;
17850                        }
17851                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17852                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17853                                new String[] {ssp}, userId);
17854                    }
17855                    break;
17856                }
17857                case Intent.ACTION_PACKAGE_ADDED:
17858                {
17859                    // Special case for adding a package: by default turn on compatibility mode.
17860                    Uri data = intent.getData();
17861                    String ssp;
17862                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17863                        final boolean replacing =
17864                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17865                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17866
17867                        try {
17868                            ApplicationInfo ai = AppGlobals.getPackageManager().
17869                                    getApplicationInfo(ssp, 0, 0);
17870                            mBatteryStatsService.notePackageInstalled(ssp,
17871                                    ai != null ? ai.versionCode : 0);
17872                        } catch (RemoteException e) {
17873                        }
17874                    }
17875                    break;
17876                }
17877                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17878                {
17879                    Uri data = intent.getData();
17880                    String ssp;
17881                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17882                        // Hide the "unsupported display" dialog if necessary.
17883                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17884                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17885                            mUnsupportedDisplaySizeDialog.dismiss();
17886                            mUnsupportedDisplaySizeDialog = null;
17887                        }
17888                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17889                    }
17890                    break;
17891                }
17892                case Intent.ACTION_TIMEZONE_CHANGED:
17893                    // If this is the time zone changed action, queue up a message that will reset
17894                    // the timezone of all currently running processes. This message will get
17895                    // queued up before the broadcast happens.
17896                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17897                    break;
17898                case Intent.ACTION_TIME_CHANGED:
17899                    // If the user set the time, let all running processes know.
17900                    final int is24Hour =
17901                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17902                                    : 0;
17903                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17904                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17905                    synchronized (stats) {
17906                        stats.noteCurrentTimeChangedLocked();
17907                    }
17908                    break;
17909                case Intent.ACTION_CLEAR_DNS_CACHE:
17910                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17911                    break;
17912                case Proxy.PROXY_CHANGE_ACTION:
17913                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17914                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17915                    break;
17916                case android.hardware.Camera.ACTION_NEW_PICTURE:
17917                case android.hardware.Camera.ACTION_NEW_VIDEO:
17918                    // These broadcasts are no longer allowed by the system, since they can
17919                    // cause significant thrashing at a crictical point (using the camera).
17920                    // Apps should use JobScehduler to monitor for media provider changes.
17921                    Slog.w(TAG, action + " no longer allowed; dropping from "
17922                            + UserHandle.formatUid(callingUid));
17923                    // Lie; we don't want to crash the app.
17924                    return ActivityManager.BROADCAST_SUCCESS;
17925            }
17926        }
17927
17928        // Add to the sticky list if requested.
17929        if (sticky) {
17930            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17931                    callingPid, callingUid)
17932                    != PackageManager.PERMISSION_GRANTED) {
17933                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17934                        + callingPid + ", uid=" + callingUid
17935                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17936                Slog.w(TAG, msg);
17937                throw new SecurityException(msg);
17938            }
17939            if (requiredPermissions != null && requiredPermissions.length > 0) {
17940                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17941                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17942                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17943            }
17944            if (intent.getComponent() != null) {
17945                throw new SecurityException(
17946                        "Sticky broadcasts can't target a specific component");
17947            }
17948            // We use userId directly here, since the "all" target is maintained
17949            // as a separate set of sticky broadcasts.
17950            if (userId != UserHandle.USER_ALL) {
17951                // But first, if this is not a broadcast to all users, then
17952                // make sure it doesn't conflict with an existing broadcast to
17953                // all users.
17954                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17955                        UserHandle.USER_ALL);
17956                if (stickies != null) {
17957                    ArrayList<Intent> list = stickies.get(intent.getAction());
17958                    if (list != null) {
17959                        int N = list.size();
17960                        int i;
17961                        for (i=0; i<N; i++) {
17962                            if (intent.filterEquals(list.get(i))) {
17963                                throw new IllegalArgumentException(
17964                                        "Sticky broadcast " + intent + " for user "
17965                                        + userId + " conflicts with existing global broadcast");
17966                            }
17967                        }
17968                    }
17969                }
17970            }
17971            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17972            if (stickies == null) {
17973                stickies = new ArrayMap<>();
17974                mStickyBroadcasts.put(userId, stickies);
17975            }
17976            ArrayList<Intent> list = stickies.get(intent.getAction());
17977            if (list == null) {
17978                list = new ArrayList<>();
17979                stickies.put(intent.getAction(), list);
17980            }
17981            final int stickiesCount = list.size();
17982            int i;
17983            for (i = 0; i < stickiesCount; i++) {
17984                if (intent.filterEquals(list.get(i))) {
17985                    // This sticky already exists, replace it.
17986                    list.set(i, new Intent(intent));
17987                    break;
17988                }
17989            }
17990            if (i >= stickiesCount) {
17991                list.add(new Intent(intent));
17992            }
17993        }
17994
17995        int[] users;
17996        if (userId == UserHandle.USER_ALL) {
17997            // Caller wants broadcast to go to all started users.
17998            users = mUserController.getStartedUserArrayLocked();
17999        } else {
18000            // Caller wants broadcast to go to one specific user.
18001            users = new int[] {userId};
18002        }
18003
18004        // Figure out who all will receive this broadcast.
18005        List receivers = null;
18006        List<BroadcastFilter> registeredReceivers = null;
18007        // Need to resolve the intent to interested receivers...
18008        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18009                 == 0) {
18010            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18011        }
18012        if (intent.getComponent() == null) {
18013            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18014                // Query one target user at a time, excluding shell-restricted users
18015                for (int i = 0; i < users.length; i++) {
18016                    if (mUserController.hasUserRestriction(
18017                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18018                        continue;
18019                    }
18020                    List<BroadcastFilter> registeredReceiversForUser =
18021                            mReceiverResolver.queryIntent(intent,
18022                                    resolvedType, false, users[i]);
18023                    if (registeredReceivers == null) {
18024                        registeredReceivers = registeredReceiversForUser;
18025                    } else if (registeredReceiversForUser != null) {
18026                        registeredReceivers.addAll(registeredReceiversForUser);
18027                    }
18028                }
18029            } else {
18030                registeredReceivers = mReceiverResolver.queryIntent(intent,
18031                        resolvedType, false, userId);
18032            }
18033        }
18034
18035        final boolean replacePending =
18036                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18037
18038        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18039                + " replacePending=" + replacePending);
18040
18041        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18042        if (!ordered && NR > 0) {
18043            // If we are not serializing this broadcast, then send the
18044            // registered receivers separately so they don't wait for the
18045            // components to be launched.
18046            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18047            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18048                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18049                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18050                    resultExtras, ordered, sticky, false, userId);
18051            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18052            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18053            if (!replaced) {
18054                queue.enqueueParallelBroadcastLocked(r);
18055                queue.scheduleBroadcastsLocked();
18056            }
18057            registeredReceivers = null;
18058            NR = 0;
18059        }
18060
18061        // Merge into one list.
18062        int ir = 0;
18063        if (receivers != null) {
18064            // A special case for PACKAGE_ADDED: do not allow the package
18065            // being added to see this broadcast.  This prevents them from
18066            // using this as a back door to get run as soon as they are
18067            // installed.  Maybe in the future we want to have a special install
18068            // broadcast or such for apps, but we'd like to deliberately make
18069            // this decision.
18070            String skipPackages[] = null;
18071            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18072                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18073                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18074                Uri data = intent.getData();
18075                if (data != null) {
18076                    String pkgName = data.getSchemeSpecificPart();
18077                    if (pkgName != null) {
18078                        skipPackages = new String[] { pkgName };
18079                    }
18080                }
18081            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18082                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18083            }
18084            if (skipPackages != null && (skipPackages.length > 0)) {
18085                for (String skipPackage : skipPackages) {
18086                    if (skipPackage != null) {
18087                        int NT = receivers.size();
18088                        for (int it=0; it<NT; it++) {
18089                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18090                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18091                                receivers.remove(it);
18092                                it--;
18093                                NT--;
18094                            }
18095                        }
18096                    }
18097                }
18098            }
18099
18100            int NT = receivers != null ? receivers.size() : 0;
18101            int it = 0;
18102            ResolveInfo curt = null;
18103            BroadcastFilter curr = null;
18104            while (it < NT && ir < NR) {
18105                if (curt == null) {
18106                    curt = (ResolveInfo)receivers.get(it);
18107                }
18108                if (curr == null) {
18109                    curr = registeredReceivers.get(ir);
18110                }
18111                if (curr.getPriority() >= curt.priority) {
18112                    // Insert this broadcast record into the final list.
18113                    receivers.add(it, curr);
18114                    ir++;
18115                    curr = null;
18116                    it++;
18117                    NT++;
18118                } else {
18119                    // Skip to the next ResolveInfo in the final list.
18120                    it++;
18121                    curt = null;
18122                }
18123            }
18124        }
18125        while (ir < NR) {
18126            if (receivers == null) {
18127                receivers = new ArrayList();
18128            }
18129            receivers.add(registeredReceivers.get(ir));
18130            ir++;
18131        }
18132
18133        if ((receivers != null && receivers.size() > 0)
18134                || resultTo != null) {
18135            BroadcastQueue queue = broadcastQueueForIntent(intent);
18136            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18137                    callerPackage, callingPid, callingUid, resolvedType,
18138                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18139                    resultData, resultExtras, ordered, sticky, false, userId);
18140
18141            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18142                    + ": prev had " + queue.mOrderedBroadcasts.size());
18143            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18144                    "Enqueueing broadcast " + r.intent.getAction());
18145
18146            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18147            if (!replaced) {
18148                queue.enqueueOrderedBroadcastLocked(r);
18149                queue.scheduleBroadcastsLocked();
18150            }
18151        } else {
18152            // There was nobody interested in the broadcast, but we still want to record
18153            // that it happened.
18154            if (intent.getComponent() == null && intent.getPackage() == null
18155                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18156                // This was an implicit broadcast... let's record it for posterity.
18157                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18158            }
18159        }
18160
18161        return ActivityManager.BROADCAST_SUCCESS;
18162    }
18163
18164    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18165            int skipCount, long dispatchTime) {
18166        final long now = SystemClock.elapsedRealtime();
18167        if (mCurBroadcastStats == null ||
18168                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18169            mLastBroadcastStats = mCurBroadcastStats;
18170            if (mLastBroadcastStats != null) {
18171                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18172                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18173            }
18174            mCurBroadcastStats = new BroadcastStats();
18175        }
18176        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18177    }
18178
18179    final Intent verifyBroadcastLocked(Intent intent) {
18180        // Refuse possible leaked file descriptors
18181        if (intent != null && intent.hasFileDescriptors() == true) {
18182            throw new IllegalArgumentException("File descriptors passed in Intent");
18183        }
18184
18185        int flags = intent.getFlags();
18186
18187        if (!mProcessesReady) {
18188            // if the caller really truly claims to know what they're doing, go
18189            // ahead and allow the broadcast without launching any receivers
18190            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18191                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18192            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18193                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18194                        + " before boot completion");
18195                throw new IllegalStateException("Cannot broadcast before boot completed");
18196            }
18197        }
18198
18199        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18200            throw new IllegalArgumentException(
18201                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18202        }
18203
18204        return intent;
18205    }
18206
18207    public final int broadcastIntent(IApplicationThread caller,
18208            Intent intent, String resolvedType, IIntentReceiver resultTo,
18209            int resultCode, String resultData, Bundle resultExtras,
18210            String[] requiredPermissions, int appOp, Bundle bOptions,
18211            boolean serialized, boolean sticky, int userId) {
18212        enforceNotIsolatedCaller("broadcastIntent");
18213        synchronized(this) {
18214            intent = verifyBroadcastLocked(intent);
18215
18216            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18217            final int callingPid = Binder.getCallingPid();
18218            final int callingUid = Binder.getCallingUid();
18219            final long origId = Binder.clearCallingIdentity();
18220            int res = broadcastIntentLocked(callerApp,
18221                    callerApp != null ? callerApp.info.packageName : null,
18222                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18223                    requiredPermissions, appOp, bOptions, serialized, sticky,
18224                    callingPid, callingUid, userId);
18225            Binder.restoreCallingIdentity(origId);
18226            return res;
18227        }
18228    }
18229
18230
18231    int broadcastIntentInPackage(String packageName, int uid,
18232            Intent intent, String resolvedType, IIntentReceiver resultTo,
18233            int resultCode, String resultData, Bundle resultExtras,
18234            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18235            int userId) {
18236        synchronized(this) {
18237            intent = verifyBroadcastLocked(intent);
18238
18239            final long origId = Binder.clearCallingIdentity();
18240            String[] requiredPermissions = requiredPermission == null ? null
18241                    : new String[] {requiredPermission};
18242            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18243                    resultTo, resultCode, resultData, resultExtras,
18244                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18245                    sticky, -1, uid, userId);
18246            Binder.restoreCallingIdentity(origId);
18247            return res;
18248        }
18249    }
18250
18251    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18252        // Refuse possible leaked file descriptors
18253        if (intent != null && intent.hasFileDescriptors() == true) {
18254            throw new IllegalArgumentException("File descriptors passed in Intent");
18255        }
18256
18257        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18258                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18259
18260        synchronized(this) {
18261            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18262                    != PackageManager.PERMISSION_GRANTED) {
18263                String msg = "Permission Denial: unbroadcastIntent() from pid="
18264                        + Binder.getCallingPid()
18265                        + ", uid=" + Binder.getCallingUid()
18266                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18267                Slog.w(TAG, msg);
18268                throw new SecurityException(msg);
18269            }
18270            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18271            if (stickies != null) {
18272                ArrayList<Intent> list = stickies.get(intent.getAction());
18273                if (list != null) {
18274                    int N = list.size();
18275                    int i;
18276                    for (i=0; i<N; i++) {
18277                        if (intent.filterEquals(list.get(i))) {
18278                            list.remove(i);
18279                            break;
18280                        }
18281                    }
18282                    if (list.size() <= 0) {
18283                        stickies.remove(intent.getAction());
18284                    }
18285                }
18286                if (stickies.size() <= 0) {
18287                    mStickyBroadcasts.remove(userId);
18288                }
18289            }
18290        }
18291    }
18292
18293    void backgroundServicesFinishedLocked(int userId) {
18294        for (BroadcastQueue queue : mBroadcastQueues) {
18295            queue.backgroundServicesFinishedLocked(userId);
18296        }
18297    }
18298
18299    public void finishReceiver(IBinder who, int resultCode, String resultData,
18300            Bundle resultExtras, boolean resultAbort, int flags) {
18301        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18302
18303        // Refuse possible leaked file descriptors
18304        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18305            throw new IllegalArgumentException("File descriptors passed in Bundle");
18306        }
18307
18308        final long origId = Binder.clearCallingIdentity();
18309        try {
18310            boolean doNext = false;
18311            BroadcastRecord r;
18312
18313            synchronized(this) {
18314                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18315                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18316                r = queue.getMatchingOrderedReceiver(who);
18317                if (r != null) {
18318                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18319                        resultData, resultExtras, resultAbort, true);
18320                }
18321            }
18322
18323            if (doNext) {
18324                r.queue.processNextBroadcast(false);
18325            }
18326            trimApplications();
18327        } finally {
18328            Binder.restoreCallingIdentity(origId);
18329        }
18330    }
18331
18332    // =========================================================
18333    // INSTRUMENTATION
18334    // =========================================================
18335
18336    public boolean startInstrumentation(ComponentName className,
18337            String profileFile, int flags, Bundle arguments,
18338            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18339            int userId, String abiOverride) {
18340        enforceNotIsolatedCaller("startInstrumentation");
18341        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18342                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18343        // Refuse possible leaked file descriptors
18344        if (arguments != null && arguments.hasFileDescriptors()) {
18345            throw new IllegalArgumentException("File descriptors passed in Bundle");
18346        }
18347
18348        synchronized(this) {
18349            InstrumentationInfo ii = null;
18350            ApplicationInfo ai = null;
18351            try {
18352                ii = mContext.getPackageManager().getInstrumentationInfo(
18353                    className, STOCK_PM_FLAGS);
18354                ai = AppGlobals.getPackageManager().getApplicationInfo(
18355                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18356            } catch (PackageManager.NameNotFoundException e) {
18357            } catch (RemoteException e) {
18358            }
18359            if (ii == null) {
18360                reportStartInstrumentationFailureLocked(watcher, className,
18361                        "Unable to find instrumentation info for: " + className);
18362                return false;
18363            }
18364            if (ai == null) {
18365                reportStartInstrumentationFailureLocked(watcher, className,
18366                        "Unable to find instrumentation target package: " + ii.targetPackage);
18367                return false;
18368            }
18369            if (!ai.hasCode()) {
18370                reportStartInstrumentationFailureLocked(watcher, className,
18371                        "Instrumentation target has no code: " + ii.targetPackage);
18372                return false;
18373            }
18374
18375            int match = mContext.getPackageManager().checkSignatures(
18376                    ii.targetPackage, ii.packageName);
18377            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18378                String msg = "Permission Denial: starting instrumentation "
18379                        + className + " from pid="
18380                        + Binder.getCallingPid()
18381                        + ", uid=" + Binder.getCallingPid()
18382                        + " not allowed because package " + ii.packageName
18383                        + " does not have a signature matching the target "
18384                        + ii.targetPackage;
18385                reportStartInstrumentationFailureLocked(watcher, className, msg);
18386                throw new SecurityException(msg);
18387            }
18388
18389            final long origId = Binder.clearCallingIdentity();
18390            // Instrumentation can kill and relaunch even persistent processes
18391            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18392                    "start instr");
18393            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18394            app.instrumentationClass = className;
18395            app.instrumentationInfo = ai;
18396            app.instrumentationProfileFile = profileFile;
18397            app.instrumentationArguments = arguments;
18398            app.instrumentationWatcher = watcher;
18399            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18400            app.instrumentationResultClass = className;
18401            Binder.restoreCallingIdentity(origId);
18402        }
18403
18404        return true;
18405    }
18406
18407    /**
18408     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18409     * error to the logs, but if somebody is watching, send the report there too.  This enables
18410     * the "am" command to report errors with more information.
18411     *
18412     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18413     * @param cn The component name of the instrumentation.
18414     * @param report The error report.
18415     */
18416    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18417            ComponentName cn, String report) {
18418        Slog.w(TAG, report);
18419        if (watcher != null) {
18420            Bundle results = new Bundle();
18421            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18422            results.putString("Error", report);
18423            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18424        }
18425    }
18426
18427    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18428        if (app.instrumentationWatcher != null) {
18429            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18430                    app.instrumentationClass, resultCode, results);
18431        }
18432
18433        // Can't call out of the system process with a lock held, so post a message.
18434        if (app.instrumentationUiAutomationConnection != null) {
18435            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18436                    app.instrumentationUiAutomationConnection).sendToTarget();
18437        }
18438
18439        app.instrumentationWatcher = null;
18440        app.instrumentationUiAutomationConnection = null;
18441        app.instrumentationClass = null;
18442        app.instrumentationInfo = null;
18443        app.instrumentationProfileFile = null;
18444        app.instrumentationArguments = null;
18445
18446        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18447                "finished inst");
18448    }
18449
18450    public void finishInstrumentation(IApplicationThread target,
18451            int resultCode, Bundle results) {
18452        int userId = UserHandle.getCallingUserId();
18453        // Refuse possible leaked file descriptors
18454        if (results != null && results.hasFileDescriptors()) {
18455            throw new IllegalArgumentException("File descriptors passed in Intent");
18456        }
18457
18458        synchronized(this) {
18459            ProcessRecord app = getRecordForAppLocked(target);
18460            if (app == null) {
18461                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18462                return;
18463            }
18464            final long origId = Binder.clearCallingIdentity();
18465            finishInstrumentationLocked(app, resultCode, results);
18466            Binder.restoreCallingIdentity(origId);
18467        }
18468    }
18469
18470    // =========================================================
18471    // CONFIGURATION
18472    // =========================================================
18473
18474    public ConfigurationInfo getDeviceConfigurationInfo() {
18475        ConfigurationInfo config = new ConfigurationInfo();
18476        synchronized (this) {
18477            config.reqTouchScreen = mConfiguration.touchscreen;
18478            config.reqKeyboardType = mConfiguration.keyboard;
18479            config.reqNavigation = mConfiguration.navigation;
18480            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18481                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18482                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18483            }
18484            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18485                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18486                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18487            }
18488            config.reqGlEsVersion = GL_ES_VERSION;
18489        }
18490        return config;
18491    }
18492
18493    ActivityStack getFocusedStack() {
18494        return mStackSupervisor.getFocusedStack();
18495    }
18496
18497    @Override
18498    public int getFocusedStackId() throws RemoteException {
18499        ActivityStack focusedStack = getFocusedStack();
18500        if (focusedStack != null) {
18501            return focusedStack.getStackId();
18502        }
18503        return -1;
18504    }
18505
18506    public Configuration getConfiguration() {
18507        Configuration ci;
18508        synchronized(this) {
18509            ci = new Configuration(mConfiguration);
18510            ci.userSetLocale = false;
18511        }
18512        return ci;
18513    }
18514
18515    @Override
18516    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18517        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18518        synchronized (this) {
18519            mSuppressResizeConfigChanges = suppress;
18520        }
18521    }
18522
18523    @Override
18524    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18525        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18526        if (fromStackId == HOME_STACK_ID) {
18527            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18528        }
18529        synchronized (this) {
18530            final long origId = Binder.clearCallingIdentity();
18531            try {
18532                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18533            } finally {
18534                Binder.restoreCallingIdentity(origId);
18535            }
18536        }
18537    }
18538
18539    @Override
18540    public void updatePersistentConfiguration(Configuration values) {
18541        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18542                "updateConfiguration()");
18543        enforceWriteSettingsPermission("updateConfiguration()");
18544        if (values == null) {
18545            throw new NullPointerException("Configuration must not be null");
18546        }
18547
18548        int userId = UserHandle.getCallingUserId();
18549
18550        synchronized(this) {
18551            final long origId = Binder.clearCallingIdentity();
18552            updateConfigurationLocked(values, null, false, true, userId);
18553            Binder.restoreCallingIdentity(origId);
18554        }
18555    }
18556
18557    private void updateFontScaleIfNeeded() {
18558        final int currentUserId;
18559        synchronized(this) {
18560            currentUserId = mUserController.getCurrentUserIdLocked();
18561        }
18562        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18563                FONT_SCALE, 1.0f, currentUserId);
18564        if (mConfiguration.fontScale != scaleFactor) {
18565            final Configuration configuration = mWindowManager.computeNewConfiguration();
18566            configuration.fontScale = scaleFactor;
18567            updatePersistentConfiguration(configuration);
18568        }
18569    }
18570
18571    private void enforceWriteSettingsPermission(String func) {
18572        int uid = Binder.getCallingUid();
18573        if (uid == Process.ROOT_UID) {
18574            return;
18575        }
18576
18577        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18578                Settings.getPackageNameForUid(mContext, uid), false)) {
18579            return;
18580        }
18581
18582        String msg = "Permission Denial: " + func + " from pid="
18583                + Binder.getCallingPid()
18584                + ", uid=" + uid
18585                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18586        Slog.w(TAG, msg);
18587        throw new SecurityException(msg);
18588    }
18589
18590    public void updateConfiguration(Configuration values) {
18591        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18592                "updateConfiguration()");
18593
18594        synchronized(this) {
18595            if (values == null && mWindowManager != null) {
18596                // sentinel: fetch the current configuration from the window manager
18597                values = mWindowManager.computeNewConfiguration();
18598            }
18599
18600            if (mWindowManager != null) {
18601                mProcessList.applyDisplaySize(mWindowManager);
18602            }
18603
18604            final long origId = Binder.clearCallingIdentity();
18605            if (values != null) {
18606                Settings.System.clearConfiguration(values);
18607            }
18608            updateConfigurationLocked(values, null, false);
18609            Binder.restoreCallingIdentity(origId);
18610        }
18611    }
18612
18613    void updateUserConfigurationLocked() {
18614        Configuration configuration = new Configuration(mConfiguration);
18615        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18616                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18617        updateConfigurationLocked(configuration, null, false);
18618    }
18619
18620    boolean updateConfigurationLocked(Configuration values,
18621            ActivityRecord starting, boolean initLocale) {
18622        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18623        return updateConfigurationLocked(values, starting, initLocale, false,
18624                UserHandle.USER_NULL);
18625    }
18626
18627    // To cache the list of supported system locales
18628    private String[] mSupportedSystemLocales = null;
18629
18630    /**
18631     * Do either or both things: (1) change the current configuration, and (2)
18632     * make sure the given activity is running with the (now) current
18633     * configuration.  Returns true if the activity has been left running, or
18634     * false if <var>starting</var> is being destroyed to match the new
18635     * configuration.
18636     *
18637     * @param userId is only used when persistent parameter is set to true to persist configuration
18638     *               for that particular user
18639     */
18640    private boolean updateConfigurationLocked(Configuration values,
18641            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18642        int changes = 0;
18643
18644        if (mWindowManager != null) {
18645            mWindowManager.deferSurfaceLayout();
18646        }
18647        if (values != null) {
18648            Configuration newConfig = new Configuration(mConfiguration);
18649            changes = newConfig.updateFrom(values);
18650            if (changes != 0) {
18651                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18652                        "Updating configuration to: " + values);
18653
18654                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18655
18656                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18657                    final LocaleList locales = values.getLocales();
18658                    int bestLocaleIndex = 0;
18659                    if (locales.size() > 1) {
18660                        if (mSupportedSystemLocales == null) {
18661                            mSupportedSystemLocales =
18662                                    Resources.getSystem().getAssets().getLocales();
18663                        }
18664                        bestLocaleIndex = Math.max(0,
18665                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18666                    }
18667                    SystemProperties.set("persist.sys.locale",
18668                            locales.get(bestLocaleIndex).toLanguageTag());
18669                    LocaleList.setDefault(locales, bestLocaleIndex);
18670                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18671                            locales.get(bestLocaleIndex)));
18672                }
18673
18674                mConfigurationSeq++;
18675                if (mConfigurationSeq <= 0) {
18676                    mConfigurationSeq = 1;
18677                }
18678                newConfig.seq = mConfigurationSeq;
18679                mConfiguration = newConfig;
18680                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18681                mUsageStatsService.reportConfigurationChange(newConfig,
18682                        mUserController.getCurrentUserIdLocked());
18683                //mUsageStatsService.noteStartConfig(newConfig);
18684
18685                final Configuration configCopy = new Configuration(mConfiguration);
18686
18687                // TODO: If our config changes, should we auto dismiss any currently
18688                // showing dialogs?
18689                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18690
18691                AttributeCache ac = AttributeCache.instance();
18692                if (ac != null) {
18693                    ac.updateConfiguration(configCopy);
18694                }
18695
18696                // Make sure all resources in our process are updated
18697                // right now, so that anyone who is going to retrieve
18698                // resource values after we return will be sure to get
18699                // the new ones.  This is especially important during
18700                // boot, where the first config change needs to guarantee
18701                // all resources have that config before following boot
18702                // code is executed.
18703                mSystemThread.applyConfigurationToResources(configCopy);
18704
18705                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18706                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18707                    msg.obj = new Configuration(configCopy);
18708                    msg.arg1 = userId;
18709                    mHandler.sendMessage(msg);
18710                }
18711
18712                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18713                if (isDensityChange) {
18714                    // Reset the unsupported display size dialog.
18715                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18716
18717                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18718                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18719                }
18720
18721                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18722                    ProcessRecord app = mLruProcesses.get(i);
18723                    try {
18724                        if (app.thread != null) {
18725                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18726                                    + app.processName + " new config " + mConfiguration);
18727                            app.thread.scheduleConfigurationChanged(configCopy);
18728                        }
18729                    } catch (Exception e) {
18730                    }
18731                }
18732                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18733                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18734                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18735                        | Intent.FLAG_RECEIVER_FOREGROUND);
18736                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18737                        null, AppOpsManager.OP_NONE, null, false, false,
18738                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18739                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18740                    // Tell the shortcut manager that the system locale changed.  It needs to know
18741                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18742                    // we "push" from here, rather than having the service listen to the broadcast.
18743                    final ShortcutServiceInternal shortcutService =
18744                            LocalServices.getService(ShortcutServiceInternal.class);
18745                    if (shortcutService != null) {
18746                        shortcutService.onSystemLocaleChangedNoLock();
18747                    }
18748
18749                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18750                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18751                    if (!mProcessesReady) {
18752                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18753                    }
18754                    broadcastIntentLocked(null, null, intent,
18755                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18756                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18757                }
18758            }
18759            // Update the configuration with WM first and check if any of the stacks need to be
18760            // resized due to the configuration change. If so, resize the stacks now and do any
18761            // relaunches if necessary. This way we don't need to relaunch again below in
18762            // ensureActivityConfigurationLocked().
18763            if (mWindowManager != null) {
18764                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18765                if (resizedStacks != null) {
18766                    for (int stackId : resizedStacks) {
18767                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18768                        mStackSupervisor.resizeStackLocked(
18769                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18770                    }
18771                }
18772            }
18773        }
18774
18775        boolean kept = true;
18776        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18777        // mainStack is null during startup.
18778        if (mainStack != null) {
18779            if (changes != 0 && starting == null) {
18780                // If the configuration changed, and the caller is not already
18781                // in the process of starting an activity, then find the top
18782                // activity to check if its configuration needs to change.
18783                starting = mainStack.topRunningActivityLocked();
18784            }
18785
18786            if (starting != null && starting.state != ActivityState.STOPPED) {
18787                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18788                // And we need to make sure at this point that all other activities
18789                // are made visible with the correct configuration.
18790                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18791                        !PRESERVE_WINDOWS);
18792            }
18793        }
18794        if (mWindowManager != null) {
18795            mWindowManager.continueSurfaceLayout();
18796        }
18797        return kept;
18798    }
18799
18800    /**
18801     * Decide based on the configuration whether we should shouw the ANR,
18802     * crash, etc dialogs.  The idea is that if there is no affordnace to
18803     * press the on-screen buttons, we shouldn't show the dialog.
18804     *
18805     * A thought: SystemUI might also want to get told about this, the Power
18806     * dialog / global actions also might want different behaviors.
18807     */
18808    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18809        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18810                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18811                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18812        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18813                                    == Configuration.UI_MODE_TYPE_CAR);
18814        return inputMethodExists && uiIsNotCarType && !inVrMode;
18815    }
18816
18817    @Override
18818    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18819        synchronized (this) {
18820            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18821            if (srec != null) {
18822                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18823            }
18824        }
18825        return false;
18826    }
18827
18828    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18829            Intent resultData) {
18830
18831        synchronized (this) {
18832            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18833            if (r != null) {
18834                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18835            }
18836            return false;
18837        }
18838    }
18839
18840    public int getLaunchedFromUid(IBinder activityToken) {
18841        ActivityRecord srec;
18842        synchronized (this) {
18843            srec = ActivityRecord.forTokenLocked(activityToken);
18844        }
18845        if (srec == null) {
18846            return -1;
18847        }
18848        return srec.launchedFromUid;
18849    }
18850
18851    public String getLaunchedFromPackage(IBinder activityToken) {
18852        ActivityRecord srec;
18853        synchronized (this) {
18854            srec = ActivityRecord.forTokenLocked(activityToken);
18855        }
18856        if (srec == null) {
18857            return null;
18858        }
18859        return srec.launchedFromPackage;
18860    }
18861
18862    // =========================================================
18863    // LIFETIME MANAGEMENT
18864    // =========================================================
18865
18866    // Returns which broadcast queue the app is the current [or imminent] receiver
18867    // on, or 'null' if the app is not an active broadcast recipient.
18868    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18869        BroadcastRecord r = app.curReceiver;
18870        if (r != null) {
18871            return r.queue;
18872        }
18873
18874        // It's not the current receiver, but it might be starting up to become one
18875        synchronized (this) {
18876            for (BroadcastQueue queue : mBroadcastQueues) {
18877                r = queue.mPendingBroadcast;
18878                if (r != null && r.curApp == app) {
18879                    // found it; report which queue it's in
18880                    return queue;
18881                }
18882            }
18883        }
18884
18885        return null;
18886    }
18887
18888    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18889            int targetUid, ComponentName targetComponent, String targetProcess) {
18890        if (!mTrackingAssociations) {
18891            return null;
18892        }
18893        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18894                = mAssociations.get(targetUid);
18895        if (components == null) {
18896            components = new ArrayMap<>();
18897            mAssociations.put(targetUid, components);
18898        }
18899        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18900        if (sourceUids == null) {
18901            sourceUids = new SparseArray<>();
18902            components.put(targetComponent, sourceUids);
18903        }
18904        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18905        if (sourceProcesses == null) {
18906            sourceProcesses = new ArrayMap<>();
18907            sourceUids.put(sourceUid, sourceProcesses);
18908        }
18909        Association ass = sourceProcesses.get(sourceProcess);
18910        if (ass == null) {
18911            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18912                    targetProcess);
18913            sourceProcesses.put(sourceProcess, ass);
18914        }
18915        ass.mCount++;
18916        ass.mNesting++;
18917        if (ass.mNesting == 1) {
18918            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18919            ass.mLastState = sourceState;
18920        }
18921        return ass;
18922    }
18923
18924    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18925            ComponentName targetComponent) {
18926        if (!mTrackingAssociations) {
18927            return;
18928        }
18929        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18930                = mAssociations.get(targetUid);
18931        if (components == null) {
18932            return;
18933        }
18934        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18935        if (sourceUids == null) {
18936            return;
18937        }
18938        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18939        if (sourceProcesses == null) {
18940            return;
18941        }
18942        Association ass = sourceProcesses.get(sourceProcess);
18943        if (ass == null || ass.mNesting <= 0) {
18944            return;
18945        }
18946        ass.mNesting--;
18947        if (ass.mNesting == 0) {
18948            long uptime = SystemClock.uptimeMillis();
18949            ass.mTime += uptime - ass.mStartTime;
18950            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18951                    += uptime - ass.mLastStateUptime;
18952            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18953        }
18954    }
18955
18956    private void noteUidProcessState(final int uid, final int state) {
18957        mBatteryStatsService.noteUidProcessState(uid, state);
18958        if (mTrackingAssociations) {
18959            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18960                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18961                        = mAssociations.valueAt(i1);
18962                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18963                    SparseArray<ArrayMap<String, Association>> sourceUids
18964                            = targetComponents.valueAt(i2);
18965                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18966                    if (sourceProcesses != null) {
18967                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18968                            Association ass = sourceProcesses.valueAt(i4);
18969                            if (ass.mNesting >= 1) {
18970                                // currently associated
18971                                long uptime = SystemClock.uptimeMillis();
18972                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18973                                        += uptime - ass.mLastStateUptime;
18974                                ass.mLastState = state;
18975                                ass.mLastStateUptime = uptime;
18976                            }
18977                        }
18978                    }
18979                }
18980            }
18981        }
18982    }
18983
18984    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18985            boolean doingAll, long now) {
18986        if (mAdjSeq == app.adjSeq) {
18987            // This adjustment has already been computed.
18988            return app.curRawAdj;
18989        }
18990
18991        if (app.thread == null) {
18992            app.adjSeq = mAdjSeq;
18993            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18994            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18995            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18996        }
18997
18998        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18999        app.adjSource = null;
19000        app.adjTarget = null;
19001        app.empty = false;
19002        app.cached = false;
19003
19004        final int activitiesSize = app.activities.size();
19005
19006        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19007            // The max adjustment doesn't allow this app to be anything
19008            // below foreground, so it is not worth doing work for it.
19009            app.adjType = "fixed";
19010            app.adjSeq = mAdjSeq;
19011            app.curRawAdj = app.maxAdj;
19012            app.foregroundActivities = false;
19013            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19014            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19015            // System processes can do UI, and when they do we want to have
19016            // them trim their memory after the user leaves the UI.  To
19017            // facilitate this, here we need to determine whether or not it
19018            // is currently showing UI.
19019            app.systemNoUi = true;
19020            if (app == TOP_APP) {
19021                app.systemNoUi = false;
19022                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19023                app.adjType = "pers-top-activity";
19024            } else if (activitiesSize > 0) {
19025                for (int j = 0; j < activitiesSize; j++) {
19026                    final ActivityRecord r = app.activities.get(j);
19027                    if (r.visible) {
19028                        app.systemNoUi = false;
19029                    }
19030                }
19031            }
19032            if (!app.systemNoUi) {
19033                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19034            }
19035            return (app.curAdj=app.maxAdj);
19036        }
19037
19038        app.systemNoUi = false;
19039
19040        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19041
19042        // Determine the importance of the process, starting with most
19043        // important to least, and assign an appropriate OOM adjustment.
19044        int adj;
19045        int schedGroup;
19046        int procState;
19047        boolean foregroundActivities = false;
19048        BroadcastQueue queue;
19049        if (app == TOP_APP) {
19050            // The last app on the list is the foreground app.
19051            adj = ProcessList.FOREGROUND_APP_ADJ;
19052            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19053            app.adjType = "top-activity";
19054            foregroundActivities = true;
19055            procState = PROCESS_STATE_CUR_TOP;
19056        } else if (app.instrumentationClass != null) {
19057            // Don't want to kill running instrumentation.
19058            adj = ProcessList.FOREGROUND_APP_ADJ;
19059            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19060            app.adjType = "instrumentation";
19061            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19062        } else if ((queue = isReceivingBroadcast(app)) != null) {
19063            // An app that is currently receiving a broadcast also
19064            // counts as being in the foreground for OOM killer purposes.
19065            // It's placed in a sched group based on the nature of the
19066            // broadcast as reflected by which queue it's active in.
19067            adj = ProcessList.FOREGROUND_APP_ADJ;
19068            schedGroup = (queue == mFgBroadcastQueue)
19069                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19070            app.adjType = "broadcast";
19071            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19072        } else if (app.executingServices.size() > 0) {
19073            // An app that is currently executing a service callback also
19074            // counts as being in the foreground.
19075            adj = ProcessList.FOREGROUND_APP_ADJ;
19076            schedGroup = app.execServicesFg ?
19077                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19078            app.adjType = "exec-service";
19079            procState = ActivityManager.PROCESS_STATE_SERVICE;
19080            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19081        } else {
19082            // As far as we know the process is empty.  We may change our mind later.
19083            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19084            // At this point we don't actually know the adjustment.  Use the cached adj
19085            // value that the caller wants us to.
19086            adj = cachedAdj;
19087            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19088            app.cached = true;
19089            app.empty = true;
19090            app.adjType = "cch-empty";
19091        }
19092
19093        // Examine all activities if not already foreground.
19094        if (!foregroundActivities && activitiesSize > 0) {
19095            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19096            for (int j = 0; j < activitiesSize; j++) {
19097                final ActivityRecord r = app.activities.get(j);
19098                if (r.app != app) {
19099                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19100                            + " instead of expected " + app);
19101                    if (r.app == null || (r.app.uid == app.uid)) {
19102                        // Only fix things up when they look sane
19103                        r.app = app;
19104                    } else {
19105                        continue;
19106                    }
19107                }
19108                if (r.visible) {
19109                    // App has a visible activity; only upgrade adjustment.
19110                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19111                        adj = ProcessList.VISIBLE_APP_ADJ;
19112                        app.adjType = "visible";
19113                    }
19114                    if (procState > PROCESS_STATE_CUR_TOP) {
19115                        procState = PROCESS_STATE_CUR_TOP;
19116                    }
19117                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19118                    app.cached = false;
19119                    app.empty = false;
19120                    foregroundActivities = true;
19121                    if (r.task != null && minLayer > 0) {
19122                        final int layer = r.task.mLayerRank;
19123                        if (layer >= 0 && minLayer > layer) {
19124                            minLayer = layer;
19125                        }
19126                    }
19127                    break;
19128                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19129                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19130                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19131                        app.adjType = "pausing";
19132                    }
19133                    if (procState > PROCESS_STATE_CUR_TOP) {
19134                        procState = PROCESS_STATE_CUR_TOP;
19135                    }
19136                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19137                    app.cached = false;
19138                    app.empty = false;
19139                    foregroundActivities = true;
19140                } else if (r.state == ActivityState.STOPPING) {
19141                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19142                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19143                        app.adjType = "stopping";
19144                    }
19145                    // For the process state, we will at this point consider the
19146                    // process to be cached.  It will be cached either as an activity
19147                    // or empty depending on whether the activity is finishing.  We do
19148                    // this so that we can treat the process as cached for purposes of
19149                    // memory trimming (determing current memory level, trim command to
19150                    // send to process) since there can be an arbitrary number of stopping
19151                    // processes and they should soon all go into the cached state.
19152                    if (!r.finishing) {
19153                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19154                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19155                        }
19156                    }
19157                    app.cached = false;
19158                    app.empty = false;
19159                    foregroundActivities = true;
19160                } else {
19161                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19162                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19163                        app.adjType = "cch-act";
19164                    }
19165                }
19166            }
19167            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19168                adj += minLayer;
19169            }
19170        }
19171
19172        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19173                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19174            if (app.foregroundServices) {
19175                // The user is aware of this app, so make it visible.
19176                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19177                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19178                app.cached = false;
19179                app.adjType = "fg-service";
19180                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19181            } else if (app.forcingToForeground != null) {
19182                // The user is aware of this app, so make it visible.
19183                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19184                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19185                app.cached = false;
19186                app.adjType = "force-fg";
19187                app.adjSource = app.forcingToForeground;
19188                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19189            }
19190        }
19191
19192        if (app == mHeavyWeightProcess) {
19193            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19194                // We don't want to kill the current heavy-weight process.
19195                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19196                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19197                app.cached = false;
19198                app.adjType = "heavy";
19199            }
19200            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19201                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19202            }
19203        }
19204
19205        if (app == mHomeProcess) {
19206            if (adj > ProcessList.HOME_APP_ADJ) {
19207                // This process is hosting what we currently consider to be the
19208                // home app, so we don't want to let it go into the background.
19209                adj = ProcessList.HOME_APP_ADJ;
19210                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19211                app.cached = false;
19212                app.adjType = "home";
19213            }
19214            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19215                procState = ActivityManager.PROCESS_STATE_HOME;
19216            }
19217        }
19218
19219        if (app == mPreviousProcess && app.activities.size() > 0) {
19220            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19221                // This was the previous process that showed UI to the user.
19222                // We want to try to keep it around more aggressively, to give
19223                // a good experience around switching between two apps.
19224                adj = ProcessList.PREVIOUS_APP_ADJ;
19225                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19226                app.cached = false;
19227                app.adjType = "previous";
19228            }
19229            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19230                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19231            }
19232        }
19233
19234        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19235                + " reason=" + app.adjType);
19236
19237        // By default, we use the computed adjustment.  It may be changed if
19238        // there are applications dependent on our services or providers, but
19239        // this gives us a baseline and makes sure we don't get into an
19240        // infinite recursion.
19241        app.adjSeq = mAdjSeq;
19242        app.curRawAdj = adj;
19243        app.hasStartedServices = false;
19244
19245        if (mBackupTarget != null && app == mBackupTarget.app) {
19246            // If possible we want to avoid killing apps while they're being backed up
19247            if (adj > ProcessList.BACKUP_APP_ADJ) {
19248                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19249                adj = ProcessList.BACKUP_APP_ADJ;
19250                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19251                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19252                }
19253                app.adjType = "backup";
19254                app.cached = false;
19255            }
19256            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19257                procState = ActivityManager.PROCESS_STATE_BACKUP;
19258            }
19259        }
19260
19261        boolean mayBeTop = false;
19262
19263        for (int is = app.services.size()-1;
19264                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19265                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19266                        || procState > ActivityManager.PROCESS_STATE_TOP);
19267                is--) {
19268            ServiceRecord s = app.services.valueAt(is);
19269            if (s.startRequested) {
19270                app.hasStartedServices = true;
19271                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19272                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19273                }
19274                if (app.hasShownUi && app != mHomeProcess) {
19275                    // If this process has shown some UI, let it immediately
19276                    // go to the LRU list because it may be pretty heavy with
19277                    // UI stuff.  We'll tag it with a label just to help
19278                    // debug and understand what is going on.
19279                    if (adj > ProcessList.SERVICE_ADJ) {
19280                        app.adjType = "cch-started-ui-services";
19281                    }
19282                } else {
19283                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19284                        // This service has seen some activity within
19285                        // recent memory, so we will keep its process ahead
19286                        // of the background processes.
19287                        if (adj > ProcessList.SERVICE_ADJ) {
19288                            adj = ProcessList.SERVICE_ADJ;
19289                            app.adjType = "started-services";
19290                            app.cached = false;
19291                        }
19292                    }
19293                    // If we have let the service slide into the background
19294                    // state, still have some text describing what it is doing
19295                    // even though the service no longer has an impact.
19296                    if (adj > ProcessList.SERVICE_ADJ) {
19297                        app.adjType = "cch-started-services";
19298                    }
19299                }
19300            }
19301
19302            app.whitelistManager = false;
19303
19304            for (int conni = s.connections.size()-1;
19305                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19306                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19307                            || procState > ActivityManager.PROCESS_STATE_TOP);
19308                    conni--) {
19309                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19310                for (int i = 0;
19311                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19312                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19313                                || procState > ActivityManager.PROCESS_STATE_TOP);
19314                        i++) {
19315                    // XXX should compute this based on the max of
19316                    // all connected clients.
19317                    ConnectionRecord cr = clist.get(i);
19318                    if (cr.binding.client == app) {
19319                        // Binding to ourself is not interesting.
19320                        continue;
19321                    }
19322                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19323                        app.whitelistManager = true;
19324                    }
19325
19326                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19327                        ProcessRecord client = cr.binding.client;
19328                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19329                                TOP_APP, doingAll, now);
19330                        int clientProcState = client.curProcState;
19331                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19332                            // If the other app is cached for any reason, for purposes here
19333                            // we are going to consider it empty.  The specific cached state
19334                            // doesn't propagate except under certain conditions.
19335                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19336                        }
19337                        String adjType = null;
19338                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19339                            // Not doing bind OOM management, so treat
19340                            // this guy more like a started service.
19341                            if (app.hasShownUi && app != mHomeProcess) {
19342                                // If this process has shown some UI, let it immediately
19343                                // go to the LRU list because it may be pretty heavy with
19344                                // UI stuff.  We'll tag it with a label just to help
19345                                // debug and understand what is going on.
19346                                if (adj > clientAdj) {
19347                                    adjType = "cch-bound-ui-services";
19348                                }
19349                                app.cached = false;
19350                                clientAdj = adj;
19351                                clientProcState = procState;
19352                            } else {
19353                                if (now >= (s.lastActivity
19354                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19355                                    // This service has not seen activity within
19356                                    // recent memory, so allow it to drop to the
19357                                    // LRU list if there is no other reason to keep
19358                                    // it around.  We'll also tag it with a label just
19359                                    // to help debug and undertand what is going on.
19360                                    if (adj > clientAdj) {
19361                                        adjType = "cch-bound-services";
19362                                    }
19363                                    clientAdj = adj;
19364                                }
19365                            }
19366                        }
19367                        if (adj > clientAdj) {
19368                            // If this process has recently shown UI, and
19369                            // the process that is binding to it is less
19370                            // important than being visible, then we don't
19371                            // care about the binding as much as we care
19372                            // about letting this process get into the LRU
19373                            // list to be killed and restarted if needed for
19374                            // memory.
19375                            if (app.hasShownUi && app != mHomeProcess
19376                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19377                                adjType = "cch-bound-ui-services";
19378                            } else {
19379                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19380                                        |Context.BIND_IMPORTANT)) != 0) {
19381                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19382                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19383                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19384                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19385                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19386                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19387                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19388                                    adj = clientAdj;
19389                                } else {
19390                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19391                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19392                                    }
19393                                }
19394                                if (!client.cached) {
19395                                    app.cached = false;
19396                                }
19397                                adjType = "service";
19398                            }
19399                        }
19400                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19401                            // This will treat important bound services identically to
19402                            // the top app, which may behave differently than generic
19403                            // foreground work.
19404                            if (client.curSchedGroup > schedGroup) {
19405                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19406                                    schedGroup = client.curSchedGroup;
19407                                } else {
19408                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19409                                }
19410                            }
19411                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19412                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19413                                    // Special handling of clients who are in the top state.
19414                                    // We *may* want to consider this process to be in the
19415                                    // top state as well, but only if there is not another
19416                                    // reason for it to be running.  Being on the top is a
19417                                    // special state, meaning you are specifically running
19418                                    // for the current top app.  If the process is already
19419                                    // running in the background for some other reason, it
19420                                    // is more important to continue considering it to be
19421                                    // in the background state.
19422                                    mayBeTop = true;
19423                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19424                                } else {
19425                                    // Special handling for above-top states (persistent
19426                                    // processes).  These should not bring the current process
19427                                    // into the top state, since they are not on top.  Instead
19428                                    // give them the best state after that.
19429                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19430                                        clientProcState =
19431                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19432                                    } else if (mWakefulness
19433                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19434                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19435                                                    != 0) {
19436                                        clientProcState =
19437                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19438                                    } else {
19439                                        clientProcState =
19440                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19441                                    }
19442                                }
19443                            }
19444                        } else {
19445                            if (clientProcState <
19446                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19447                                clientProcState =
19448                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19449                            }
19450                        }
19451                        if (procState > clientProcState) {
19452                            procState = clientProcState;
19453                        }
19454                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19455                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19456                            app.pendingUiClean = true;
19457                        }
19458                        if (adjType != null) {
19459                            app.adjType = adjType;
19460                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19461                                    .REASON_SERVICE_IN_USE;
19462                            app.adjSource = cr.binding.client;
19463                            app.adjSourceProcState = clientProcState;
19464                            app.adjTarget = s.name;
19465                        }
19466                    }
19467                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19468                        app.treatLikeActivity = true;
19469                    }
19470                    final ActivityRecord a = cr.activity;
19471                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19472                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19473                            (a.visible || a.state == ActivityState.RESUMED ||
19474                             a.state == ActivityState.PAUSING)) {
19475                            adj = ProcessList.FOREGROUND_APP_ADJ;
19476                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19477                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19478                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19479                                } else {
19480                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19481                                }
19482                            }
19483                            app.cached = false;
19484                            app.adjType = "service";
19485                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19486                                    .REASON_SERVICE_IN_USE;
19487                            app.adjSource = a;
19488                            app.adjSourceProcState = procState;
19489                            app.adjTarget = s.name;
19490                        }
19491                    }
19492                }
19493            }
19494        }
19495
19496        for (int provi = app.pubProviders.size()-1;
19497                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19498                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19499                        || procState > ActivityManager.PROCESS_STATE_TOP);
19500                provi--) {
19501            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19502            for (int i = cpr.connections.size()-1;
19503                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19504                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19505                            || procState > ActivityManager.PROCESS_STATE_TOP);
19506                    i--) {
19507                ContentProviderConnection conn = cpr.connections.get(i);
19508                ProcessRecord client = conn.client;
19509                if (client == app) {
19510                    // Being our own client is not interesting.
19511                    continue;
19512                }
19513                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19514                int clientProcState = client.curProcState;
19515                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19516                    // If the other app is cached for any reason, for purposes here
19517                    // we are going to consider it empty.
19518                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19519                }
19520                if (adj > clientAdj) {
19521                    if (app.hasShownUi && app != mHomeProcess
19522                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19523                        app.adjType = "cch-ui-provider";
19524                    } else {
19525                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19526                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19527                        app.adjType = "provider";
19528                    }
19529                    app.cached &= client.cached;
19530                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19531                            .REASON_PROVIDER_IN_USE;
19532                    app.adjSource = client;
19533                    app.adjSourceProcState = clientProcState;
19534                    app.adjTarget = cpr.name;
19535                }
19536                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19537                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19538                        // Special handling of clients who are in the top state.
19539                        // We *may* want to consider this process to be in the
19540                        // top state as well, but only if there is not another
19541                        // reason for it to be running.  Being on the top is a
19542                        // special state, meaning you are specifically running
19543                        // for the current top app.  If the process is already
19544                        // running in the background for some other reason, it
19545                        // is more important to continue considering it to be
19546                        // in the background state.
19547                        mayBeTop = true;
19548                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19549                    } else {
19550                        // Special handling for above-top states (persistent
19551                        // processes).  These should not bring the current process
19552                        // into the top state, since they are not on top.  Instead
19553                        // give them the best state after that.
19554                        clientProcState =
19555                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19556                    }
19557                }
19558                if (procState > clientProcState) {
19559                    procState = clientProcState;
19560                }
19561                if (client.curSchedGroup > schedGroup) {
19562                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19563                }
19564            }
19565            // If the provider has external (non-framework) process
19566            // dependencies, ensure that its adjustment is at least
19567            // FOREGROUND_APP_ADJ.
19568            if (cpr.hasExternalProcessHandles()) {
19569                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19570                    adj = ProcessList.FOREGROUND_APP_ADJ;
19571                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19572                    app.cached = false;
19573                    app.adjType = "provider";
19574                    app.adjTarget = cpr.name;
19575                }
19576                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19577                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19578                }
19579            }
19580        }
19581
19582        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19583            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19584                adj = ProcessList.PREVIOUS_APP_ADJ;
19585                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19586                app.cached = false;
19587                app.adjType = "provider";
19588            }
19589            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19590                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19591            }
19592        }
19593
19594        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19595            // A client of one of our services or providers is in the top state.  We
19596            // *may* want to be in the top state, but not if we are already running in
19597            // the background for some other reason.  For the decision here, we are going
19598            // to pick out a few specific states that we want to remain in when a client
19599            // is top (states that tend to be longer-term) and otherwise allow it to go
19600            // to the top state.
19601            switch (procState) {
19602                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19603                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19604                case ActivityManager.PROCESS_STATE_SERVICE:
19605                    // These all are longer-term states, so pull them up to the top
19606                    // of the background states, but not all the way to the top state.
19607                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19608                    break;
19609                default:
19610                    // Otherwise, top is a better choice, so take it.
19611                    procState = ActivityManager.PROCESS_STATE_TOP;
19612                    break;
19613            }
19614        }
19615
19616        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19617            if (app.hasClientActivities) {
19618                // This is a cached process, but with client activities.  Mark it so.
19619                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19620                app.adjType = "cch-client-act";
19621            } else if (app.treatLikeActivity) {
19622                // This is a cached process, but somebody wants us to treat it like it has
19623                // an activity, okay!
19624                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19625                app.adjType = "cch-as-act";
19626            }
19627        }
19628
19629        if (adj == ProcessList.SERVICE_ADJ) {
19630            if (doingAll) {
19631                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19632                mNewNumServiceProcs++;
19633                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19634                if (!app.serviceb) {
19635                    // This service isn't far enough down on the LRU list to
19636                    // normally be a B service, but if we are low on RAM and it
19637                    // is large we want to force it down since we would prefer to
19638                    // keep launcher over it.
19639                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19640                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19641                        app.serviceHighRam = true;
19642                        app.serviceb = true;
19643                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19644                    } else {
19645                        mNewNumAServiceProcs++;
19646                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19647                    }
19648                } else {
19649                    app.serviceHighRam = false;
19650                }
19651            }
19652            if (app.serviceb) {
19653                adj = ProcessList.SERVICE_B_ADJ;
19654            }
19655        }
19656
19657        app.curRawAdj = adj;
19658
19659        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19660        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19661        if (adj > app.maxAdj) {
19662            adj = app.maxAdj;
19663            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19664                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19665            }
19666        }
19667
19668        // Do final modification to adj.  Everything we do between here and applying
19669        // the final setAdj must be done in this function, because we will also use
19670        // it when computing the final cached adj later.  Note that we don't need to
19671        // worry about this for max adj above, since max adj will always be used to
19672        // keep it out of the cached vaues.
19673        app.curAdj = app.modifyRawOomAdj(adj);
19674        app.curSchedGroup = schedGroup;
19675        app.curProcState = procState;
19676        app.foregroundActivities = foregroundActivities;
19677
19678        return app.curRawAdj;
19679    }
19680
19681    /**
19682     * Record new PSS sample for a process.
19683     */
19684    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19685            long now) {
19686        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19687                swapPss * 1024);
19688        proc.lastPssTime = now;
19689        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19690        if (DEBUG_PSS) Slog.d(TAG_PSS,
19691                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19692                + " state=" + ProcessList.makeProcStateString(procState));
19693        if (proc.initialIdlePss == 0) {
19694            proc.initialIdlePss = pss;
19695        }
19696        proc.lastPss = pss;
19697        proc.lastSwapPss = swapPss;
19698        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19699            proc.lastCachedPss = pss;
19700            proc.lastCachedSwapPss = swapPss;
19701        }
19702
19703        final SparseArray<Pair<Long, String>> watchUids
19704                = mMemWatchProcesses.getMap().get(proc.processName);
19705        Long check = null;
19706        if (watchUids != null) {
19707            Pair<Long, String> val = watchUids.get(proc.uid);
19708            if (val == null) {
19709                val = watchUids.get(0);
19710            }
19711            if (val != null) {
19712                check = val.first;
19713            }
19714        }
19715        if (check != null) {
19716            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19717                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19718                if (!isDebuggable) {
19719                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19720                        isDebuggable = true;
19721                    }
19722                }
19723                if (isDebuggable) {
19724                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19725                    final ProcessRecord myProc = proc;
19726                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19727                    mMemWatchDumpProcName = proc.processName;
19728                    mMemWatchDumpFile = heapdumpFile.toString();
19729                    mMemWatchDumpPid = proc.pid;
19730                    mMemWatchDumpUid = proc.uid;
19731                    BackgroundThread.getHandler().post(new Runnable() {
19732                        @Override
19733                        public void run() {
19734                            revokeUriPermission(ActivityThread.currentActivityThread()
19735                                            .getApplicationThread(),
19736                                    DumpHeapActivity.JAVA_URI,
19737                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19738                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19739                                    UserHandle.myUserId());
19740                            ParcelFileDescriptor fd = null;
19741                            try {
19742                                heapdumpFile.delete();
19743                                fd = ParcelFileDescriptor.open(heapdumpFile,
19744                                        ParcelFileDescriptor.MODE_CREATE |
19745                                                ParcelFileDescriptor.MODE_TRUNCATE |
19746                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19747                                                ParcelFileDescriptor.MODE_APPEND);
19748                                IApplicationThread thread = myProc.thread;
19749                                if (thread != null) {
19750                                    try {
19751                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19752                                                "Requesting dump heap from "
19753                                                + myProc + " to " + heapdumpFile);
19754                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19755                                    } catch (RemoteException e) {
19756                                    }
19757                                }
19758                            } catch (FileNotFoundException e) {
19759                                e.printStackTrace();
19760                            } finally {
19761                                if (fd != null) {
19762                                    try {
19763                                        fd.close();
19764                                    } catch (IOException e) {
19765                                    }
19766                                }
19767                            }
19768                        }
19769                    });
19770                } else {
19771                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19772                            + ", but debugging not enabled");
19773                }
19774            }
19775        }
19776    }
19777
19778    /**
19779     * Schedule PSS collection of a process.
19780     */
19781    void requestPssLocked(ProcessRecord proc, int procState) {
19782        if (mPendingPssProcesses.contains(proc)) {
19783            return;
19784        }
19785        if (mPendingPssProcesses.size() == 0) {
19786            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19787        }
19788        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19789        proc.pssProcState = procState;
19790        mPendingPssProcesses.add(proc);
19791    }
19792
19793    /**
19794     * Schedule PSS collection of all processes.
19795     */
19796    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19797        if (!always) {
19798            if (now < (mLastFullPssTime +
19799                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19800                return;
19801            }
19802        }
19803        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19804        mLastFullPssTime = now;
19805        mFullPssPending = true;
19806        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19807        mPendingPssProcesses.clear();
19808        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19809            ProcessRecord app = mLruProcesses.get(i);
19810            if (app.thread == null
19811                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19812                continue;
19813            }
19814            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19815                app.pssProcState = app.setProcState;
19816                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19817                        mTestPssMode, isSleepingLocked(), now);
19818                mPendingPssProcesses.add(app);
19819            }
19820        }
19821        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19822    }
19823
19824    public void setTestPssMode(boolean enabled) {
19825        synchronized (this) {
19826            mTestPssMode = enabled;
19827            if (enabled) {
19828                // Whenever we enable the mode, we want to take a snapshot all of current
19829                // process mem use.
19830                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19831            }
19832        }
19833    }
19834
19835    /**
19836     * Ask a given process to GC right now.
19837     */
19838    final void performAppGcLocked(ProcessRecord app) {
19839        try {
19840            app.lastRequestedGc = SystemClock.uptimeMillis();
19841            if (app.thread != null) {
19842                if (app.reportLowMemory) {
19843                    app.reportLowMemory = false;
19844                    app.thread.scheduleLowMemory();
19845                } else {
19846                    app.thread.processInBackground();
19847                }
19848            }
19849        } catch (Exception e) {
19850            // whatever.
19851        }
19852    }
19853
19854    /**
19855     * Returns true if things are idle enough to perform GCs.
19856     */
19857    private final boolean canGcNowLocked() {
19858        boolean processingBroadcasts = false;
19859        for (BroadcastQueue q : mBroadcastQueues) {
19860            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19861                processingBroadcasts = true;
19862            }
19863        }
19864        return !processingBroadcasts
19865                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19866    }
19867
19868    /**
19869     * Perform GCs on all processes that are waiting for it, but only
19870     * if things are idle.
19871     */
19872    final void performAppGcsLocked() {
19873        final int N = mProcessesToGc.size();
19874        if (N <= 0) {
19875            return;
19876        }
19877        if (canGcNowLocked()) {
19878            while (mProcessesToGc.size() > 0) {
19879                ProcessRecord proc = mProcessesToGc.remove(0);
19880                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19881                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19882                            <= SystemClock.uptimeMillis()) {
19883                        // To avoid spamming the system, we will GC processes one
19884                        // at a time, waiting a few seconds between each.
19885                        performAppGcLocked(proc);
19886                        scheduleAppGcsLocked();
19887                        return;
19888                    } else {
19889                        // It hasn't been long enough since we last GCed this
19890                        // process...  put it in the list to wait for its time.
19891                        addProcessToGcListLocked(proc);
19892                        break;
19893                    }
19894                }
19895            }
19896
19897            scheduleAppGcsLocked();
19898        }
19899    }
19900
19901    /**
19902     * If all looks good, perform GCs on all processes waiting for them.
19903     */
19904    final void performAppGcsIfAppropriateLocked() {
19905        if (canGcNowLocked()) {
19906            performAppGcsLocked();
19907            return;
19908        }
19909        // Still not idle, wait some more.
19910        scheduleAppGcsLocked();
19911    }
19912
19913    /**
19914     * Schedule the execution of all pending app GCs.
19915     */
19916    final void scheduleAppGcsLocked() {
19917        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19918
19919        if (mProcessesToGc.size() > 0) {
19920            // Schedule a GC for the time to the next process.
19921            ProcessRecord proc = mProcessesToGc.get(0);
19922            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19923
19924            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19925            long now = SystemClock.uptimeMillis();
19926            if (when < (now+GC_TIMEOUT)) {
19927                when = now + GC_TIMEOUT;
19928            }
19929            mHandler.sendMessageAtTime(msg, when);
19930        }
19931    }
19932
19933    /**
19934     * Add a process to the array of processes waiting to be GCed.  Keeps the
19935     * list in sorted order by the last GC time.  The process can't already be
19936     * on the list.
19937     */
19938    final void addProcessToGcListLocked(ProcessRecord proc) {
19939        boolean added = false;
19940        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19941            if (mProcessesToGc.get(i).lastRequestedGc <
19942                    proc.lastRequestedGc) {
19943                added = true;
19944                mProcessesToGc.add(i+1, proc);
19945                break;
19946            }
19947        }
19948        if (!added) {
19949            mProcessesToGc.add(0, proc);
19950        }
19951    }
19952
19953    /**
19954     * Set up to ask a process to GC itself.  This will either do it
19955     * immediately, or put it on the list of processes to gc the next
19956     * time things are idle.
19957     */
19958    final void scheduleAppGcLocked(ProcessRecord app) {
19959        long now = SystemClock.uptimeMillis();
19960        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19961            return;
19962        }
19963        if (!mProcessesToGc.contains(app)) {
19964            addProcessToGcListLocked(app);
19965            scheduleAppGcsLocked();
19966        }
19967    }
19968
19969    final void checkExcessivePowerUsageLocked(boolean doKills) {
19970        updateCpuStatsNow();
19971
19972        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19973        boolean doWakeKills = doKills;
19974        boolean doCpuKills = doKills;
19975        if (mLastPowerCheckRealtime == 0) {
19976            doWakeKills = false;
19977        }
19978        if (mLastPowerCheckUptime == 0) {
19979            doCpuKills = false;
19980        }
19981        if (stats.isScreenOn()) {
19982            doWakeKills = false;
19983        }
19984        final long curRealtime = SystemClock.elapsedRealtime();
19985        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19986        final long curUptime = SystemClock.uptimeMillis();
19987        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19988        mLastPowerCheckRealtime = curRealtime;
19989        mLastPowerCheckUptime = curUptime;
19990        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19991            doWakeKills = false;
19992        }
19993        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19994            doCpuKills = false;
19995        }
19996        int i = mLruProcesses.size();
19997        while (i > 0) {
19998            i--;
19999            ProcessRecord app = mLruProcesses.get(i);
20000            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20001                long wtime;
20002                synchronized (stats) {
20003                    wtime = stats.getProcessWakeTime(app.info.uid,
20004                            app.pid, curRealtime);
20005                }
20006                long wtimeUsed = wtime - app.lastWakeTime;
20007                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20008                if (DEBUG_POWER) {
20009                    StringBuilder sb = new StringBuilder(128);
20010                    sb.append("Wake for ");
20011                    app.toShortString(sb);
20012                    sb.append(": over ");
20013                    TimeUtils.formatDuration(realtimeSince, sb);
20014                    sb.append(" used ");
20015                    TimeUtils.formatDuration(wtimeUsed, sb);
20016                    sb.append(" (");
20017                    sb.append((wtimeUsed*100)/realtimeSince);
20018                    sb.append("%)");
20019                    Slog.i(TAG_POWER, sb.toString());
20020                    sb.setLength(0);
20021                    sb.append("CPU for ");
20022                    app.toShortString(sb);
20023                    sb.append(": over ");
20024                    TimeUtils.formatDuration(uptimeSince, sb);
20025                    sb.append(" used ");
20026                    TimeUtils.formatDuration(cputimeUsed, sb);
20027                    sb.append(" (");
20028                    sb.append((cputimeUsed*100)/uptimeSince);
20029                    sb.append("%)");
20030                    Slog.i(TAG_POWER, sb.toString());
20031                }
20032                // If a process has held a wake lock for more
20033                // than 50% of the time during this period,
20034                // that sounds bad.  Kill!
20035                if (doWakeKills && realtimeSince > 0
20036                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20037                    synchronized (stats) {
20038                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20039                                realtimeSince, wtimeUsed);
20040                    }
20041                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20042                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20043                } else if (doCpuKills && uptimeSince > 0
20044                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20045                    synchronized (stats) {
20046                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20047                                uptimeSince, cputimeUsed);
20048                    }
20049                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20050                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20051                } else {
20052                    app.lastWakeTime = wtime;
20053                    app.lastCpuTime = app.curCpuTime;
20054                }
20055            }
20056        }
20057    }
20058
20059    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20060            long nowElapsed) {
20061        boolean success = true;
20062
20063        if (app.curRawAdj != app.setRawAdj) {
20064            app.setRawAdj = app.curRawAdj;
20065        }
20066
20067        int changes = 0;
20068
20069        if (app.curAdj != app.setAdj) {
20070            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20071            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20072                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20073                    + app.adjType);
20074            app.setAdj = app.curAdj;
20075        }
20076
20077        if (app.setSchedGroup != app.curSchedGroup) {
20078            app.setSchedGroup = app.curSchedGroup;
20079            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20080                    "Setting sched group of " + app.processName
20081                    + " to " + app.curSchedGroup);
20082            if (app.waitingToKill != null && app.curReceiver == null
20083                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20084                app.kill(app.waitingToKill, true);
20085                success = false;
20086            } else {
20087                int processGroup;
20088                switch (app.curSchedGroup) {
20089                    case ProcessList.SCHED_GROUP_BACKGROUND:
20090                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20091                        break;
20092                    case ProcessList.SCHED_GROUP_TOP_APP:
20093                        processGroup = Process.THREAD_GROUP_TOP_APP;
20094                        break;
20095                    default:
20096                        processGroup = Process.THREAD_GROUP_DEFAULT;
20097                        break;
20098                }
20099                if (true) {
20100                    long oldId = Binder.clearCallingIdentity();
20101                    try {
20102                        Process.setProcessGroup(app.pid, processGroup);
20103                    } catch (Exception e) {
20104                        Slog.w(TAG, "Failed setting process group of " + app.pid
20105                                + " to " + app.curSchedGroup);
20106                        e.printStackTrace();
20107                    } finally {
20108                        Binder.restoreCallingIdentity(oldId);
20109                    }
20110                } else {
20111                    if (app.thread != null) {
20112                        try {
20113                            app.thread.setSchedulingGroup(processGroup);
20114                        } catch (RemoteException e) {
20115                        }
20116                    }
20117                }
20118            }
20119        }
20120        if (app.repForegroundActivities != app.foregroundActivities) {
20121            app.repForegroundActivities = app.foregroundActivities;
20122            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20123        }
20124        if (app.repProcState != app.curProcState) {
20125            app.repProcState = app.curProcState;
20126            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20127            if (app.thread != null) {
20128                try {
20129                    if (false) {
20130                        //RuntimeException h = new RuntimeException("here");
20131                        Slog.i(TAG, "Sending new process state " + app.repProcState
20132                                + " to " + app /*, h*/);
20133                    }
20134                    app.thread.setProcessState(app.repProcState);
20135                } catch (RemoteException e) {
20136                }
20137            }
20138        }
20139        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20140                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20141            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20142                // Experimental code to more aggressively collect pss while
20143                // running test...  the problem is that this tends to collect
20144                // the data right when a process is transitioning between process
20145                // states, which well tend to give noisy data.
20146                long start = SystemClock.uptimeMillis();
20147                long pss = Debug.getPss(app.pid, mTmpLong, null);
20148                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20149                mPendingPssProcesses.remove(app);
20150                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20151                        + " to " + app.curProcState + ": "
20152                        + (SystemClock.uptimeMillis()-start) + "ms");
20153            }
20154            app.lastStateTime = now;
20155            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20156                    mTestPssMode, isSleepingLocked(), now);
20157            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20158                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20159                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20160                    + (app.nextPssTime-now) + ": " + app);
20161        } else {
20162            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20163                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20164                    mTestPssMode)))) {
20165                requestPssLocked(app, app.setProcState);
20166                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20167                        mTestPssMode, isSleepingLocked(), now);
20168            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20169                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20170        }
20171        if (app.setProcState != app.curProcState) {
20172            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20173                    "Proc state change of " + app.processName
20174                            + " to " + app.curProcState);
20175            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20176            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20177            if (setImportant && !curImportant) {
20178                // This app is no longer something we consider important enough to allow to
20179                // use arbitrary amounts of battery power.  Note
20180                // its current wake lock time to later know to kill it if
20181                // it is not behaving well.
20182                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20183                synchronized (stats) {
20184                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20185                            app.pid, nowElapsed);
20186                }
20187                app.lastCpuTime = app.curCpuTime;
20188
20189            }
20190            // Inform UsageStats of important process state change
20191            // Must be called before updating setProcState
20192            maybeUpdateUsageStatsLocked(app, nowElapsed);
20193
20194            app.setProcState = app.curProcState;
20195            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20196                app.notCachedSinceIdle = false;
20197            }
20198            if (!doingAll) {
20199                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20200            } else {
20201                app.procStateChanged = true;
20202            }
20203        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20204                > USAGE_STATS_INTERACTION_INTERVAL) {
20205            // For apps that sit around for a long time in the interactive state, we need
20206            // to report this at least once a day so they don't go idle.
20207            maybeUpdateUsageStatsLocked(app, nowElapsed);
20208        }
20209
20210        if (changes != 0) {
20211            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20212                    "Changes in " + app + ": " + changes);
20213            int i = mPendingProcessChanges.size()-1;
20214            ProcessChangeItem item = null;
20215            while (i >= 0) {
20216                item = mPendingProcessChanges.get(i);
20217                if (item.pid == app.pid) {
20218                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20219                            "Re-using existing item: " + item);
20220                    break;
20221                }
20222                i--;
20223            }
20224            if (i < 0) {
20225                // No existing item in pending changes; need a new one.
20226                final int NA = mAvailProcessChanges.size();
20227                if (NA > 0) {
20228                    item = mAvailProcessChanges.remove(NA-1);
20229                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20230                            "Retrieving available item: " + item);
20231                } else {
20232                    item = new ProcessChangeItem();
20233                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20234                            "Allocating new item: " + item);
20235                }
20236                item.changes = 0;
20237                item.pid = app.pid;
20238                item.uid = app.info.uid;
20239                if (mPendingProcessChanges.size() == 0) {
20240                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20241                            "*** Enqueueing dispatch processes changed!");
20242                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20243                }
20244                mPendingProcessChanges.add(item);
20245            }
20246            item.changes |= changes;
20247            item.processState = app.repProcState;
20248            item.foregroundActivities = app.repForegroundActivities;
20249            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20250                    "Item " + Integer.toHexString(System.identityHashCode(item))
20251                    + " " + app.toShortString() + ": changes=" + item.changes
20252                    + " procState=" + item.processState
20253                    + " foreground=" + item.foregroundActivities
20254                    + " type=" + app.adjType + " source=" + app.adjSource
20255                    + " target=" + app.adjTarget);
20256        }
20257
20258        return success;
20259    }
20260
20261    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20262        final UidRecord.ChangeItem pendingChange;
20263        if (uidRec == null || uidRec.pendingChange == null) {
20264            if (mPendingUidChanges.size() == 0) {
20265                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20266                        "*** Enqueueing dispatch uid changed!");
20267                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20268            }
20269            final int NA = mAvailUidChanges.size();
20270            if (NA > 0) {
20271                pendingChange = mAvailUidChanges.remove(NA-1);
20272                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20273                        "Retrieving available item: " + pendingChange);
20274            } else {
20275                pendingChange = new UidRecord.ChangeItem();
20276                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20277                        "Allocating new item: " + pendingChange);
20278            }
20279            if (uidRec != null) {
20280                uidRec.pendingChange = pendingChange;
20281                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20282                    // If this uid is going away, and we haven't yet reported it is gone,
20283                    // then do so now.
20284                    change = UidRecord.CHANGE_GONE_IDLE;
20285                }
20286            } else if (uid < 0) {
20287                throw new IllegalArgumentException("No UidRecord or uid");
20288            }
20289            pendingChange.uidRecord = uidRec;
20290            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20291            mPendingUidChanges.add(pendingChange);
20292        } else {
20293            pendingChange = uidRec.pendingChange;
20294            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20295                change = UidRecord.CHANGE_GONE_IDLE;
20296            }
20297        }
20298        pendingChange.change = change;
20299        pendingChange.processState = uidRec != null
20300                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20301    }
20302
20303    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20304            String authority) {
20305        if (app == null) return;
20306        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20307            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20308            if (userState == null) return;
20309            final long now = SystemClock.elapsedRealtime();
20310            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20311            if (lastReported == null || lastReported < now - 60 * 1000L) {
20312                mUsageStatsService.reportContentProviderUsage(
20313                        authority, providerPkgName, app.userId);
20314                userState.mProviderLastReportedFg.put(authority, now);
20315            }
20316        }
20317    }
20318
20319    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20320        if (DEBUG_USAGE_STATS) {
20321            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20322                    + "] state changes: old = " + app.setProcState + ", new = "
20323                    + app.curProcState);
20324        }
20325        if (mUsageStatsService == null) {
20326            return;
20327        }
20328        boolean isInteraction;
20329        // To avoid some abuse patterns, we are going to be careful about what we consider
20330        // to be an app interaction.  Being the top activity doesn't count while the display
20331        // is sleeping, nor do short foreground services.
20332        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20333            isInteraction = true;
20334            app.fgInteractionTime = 0;
20335        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20336            if (app.fgInteractionTime == 0) {
20337                app.fgInteractionTime = nowElapsed;
20338                isInteraction = false;
20339            } else {
20340                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20341            }
20342        } else {
20343            isInteraction = app.curProcState
20344                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20345            app.fgInteractionTime = 0;
20346        }
20347        if (isInteraction && (!app.reportedInteraction
20348                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20349            app.interactionEventTime = nowElapsed;
20350            String[] packages = app.getPackageList();
20351            if (packages != null) {
20352                for (int i = 0; i < packages.length; i++) {
20353                    mUsageStatsService.reportEvent(packages[i], app.userId,
20354                            UsageEvents.Event.SYSTEM_INTERACTION);
20355                }
20356            }
20357        }
20358        app.reportedInteraction = isInteraction;
20359        if (!isInteraction) {
20360            app.interactionEventTime = 0;
20361        }
20362    }
20363
20364    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20365        if (proc.thread != null) {
20366            if (proc.baseProcessTracker != null) {
20367                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20368            }
20369        }
20370    }
20371
20372    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20373            ProcessRecord TOP_APP, boolean doingAll, long now) {
20374        if (app.thread == null) {
20375            return false;
20376        }
20377
20378        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20379
20380        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20381    }
20382
20383    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20384            boolean oomAdj) {
20385        if (isForeground != proc.foregroundServices) {
20386            proc.foregroundServices = isForeground;
20387            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20388                    proc.info.uid);
20389            if (isForeground) {
20390                if (curProcs == null) {
20391                    curProcs = new ArrayList<ProcessRecord>();
20392                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20393                }
20394                if (!curProcs.contains(proc)) {
20395                    curProcs.add(proc);
20396                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20397                            proc.info.packageName, proc.info.uid);
20398                }
20399            } else {
20400                if (curProcs != null) {
20401                    if (curProcs.remove(proc)) {
20402                        mBatteryStatsService.noteEvent(
20403                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20404                                proc.info.packageName, proc.info.uid);
20405                        if (curProcs.size() <= 0) {
20406                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20407                        }
20408                    }
20409                }
20410            }
20411            if (oomAdj) {
20412                updateOomAdjLocked();
20413            }
20414        }
20415    }
20416
20417    private final ActivityRecord resumedAppLocked() {
20418        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20419        String pkg;
20420        int uid;
20421        if (act != null) {
20422            pkg = act.packageName;
20423            uid = act.info.applicationInfo.uid;
20424        } else {
20425            pkg = null;
20426            uid = -1;
20427        }
20428        // Has the UID or resumed package name changed?
20429        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20430                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20431            if (mCurResumedPackage != null) {
20432                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20433                        mCurResumedPackage, mCurResumedUid);
20434            }
20435            mCurResumedPackage = pkg;
20436            mCurResumedUid = uid;
20437            if (mCurResumedPackage != null) {
20438                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20439                        mCurResumedPackage, mCurResumedUid);
20440            }
20441        }
20442        return act;
20443    }
20444
20445    final boolean updateOomAdjLocked(ProcessRecord app) {
20446        final ActivityRecord TOP_ACT = resumedAppLocked();
20447        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20448        final boolean wasCached = app.cached;
20449
20450        mAdjSeq++;
20451
20452        // This is the desired cached adjusment we want to tell it to use.
20453        // If our app is currently cached, we know it, and that is it.  Otherwise,
20454        // we don't know it yet, and it needs to now be cached we will then
20455        // need to do a complete oom adj.
20456        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20457                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20458        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20459                SystemClock.uptimeMillis());
20460        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20461            // Changed to/from cached state, so apps after it in the LRU
20462            // list may also be changed.
20463            updateOomAdjLocked();
20464        }
20465        return success;
20466    }
20467
20468    final void updateOomAdjLocked() {
20469        final ActivityRecord TOP_ACT = resumedAppLocked();
20470        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20471        final long now = SystemClock.uptimeMillis();
20472        final long nowElapsed = SystemClock.elapsedRealtime();
20473        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20474        final int N = mLruProcesses.size();
20475
20476        if (false) {
20477            RuntimeException e = new RuntimeException();
20478            e.fillInStackTrace();
20479            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20480        }
20481
20482        // Reset state in all uid records.
20483        for (int i=mActiveUids.size()-1; i>=0; i--) {
20484            final UidRecord uidRec = mActiveUids.valueAt(i);
20485            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20486                    "Starting update of " + uidRec);
20487            uidRec.reset();
20488        }
20489
20490        mStackSupervisor.rankTaskLayersIfNeeded();
20491
20492        mAdjSeq++;
20493        mNewNumServiceProcs = 0;
20494        mNewNumAServiceProcs = 0;
20495
20496        final int emptyProcessLimit;
20497        final int cachedProcessLimit;
20498        if (mProcessLimit <= 0) {
20499            emptyProcessLimit = cachedProcessLimit = 0;
20500        } else if (mProcessLimit == 1) {
20501            emptyProcessLimit = 1;
20502            cachedProcessLimit = 0;
20503        } else {
20504            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20505            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20506        }
20507
20508        // Let's determine how many processes we have running vs.
20509        // how many slots we have for background processes; we may want
20510        // to put multiple processes in a slot of there are enough of
20511        // them.
20512        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20513                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20514        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20515        if (numEmptyProcs > cachedProcessLimit) {
20516            // If there are more empty processes than our limit on cached
20517            // processes, then use the cached process limit for the factor.
20518            // This ensures that the really old empty processes get pushed
20519            // down to the bottom, so if we are running low on memory we will
20520            // have a better chance at keeping around more cached processes
20521            // instead of a gazillion empty processes.
20522            numEmptyProcs = cachedProcessLimit;
20523        }
20524        int emptyFactor = numEmptyProcs/numSlots;
20525        if (emptyFactor < 1) emptyFactor = 1;
20526        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20527        if (cachedFactor < 1) cachedFactor = 1;
20528        int stepCached = 0;
20529        int stepEmpty = 0;
20530        int numCached = 0;
20531        int numEmpty = 0;
20532        int numTrimming = 0;
20533
20534        mNumNonCachedProcs = 0;
20535        mNumCachedHiddenProcs = 0;
20536
20537        // First update the OOM adjustment for each of the
20538        // application processes based on their current state.
20539        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20540        int nextCachedAdj = curCachedAdj+1;
20541        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20542        int nextEmptyAdj = curEmptyAdj+2;
20543        for (int i=N-1; i>=0; i--) {
20544            ProcessRecord app = mLruProcesses.get(i);
20545            if (!app.killedByAm && app.thread != null) {
20546                app.procStateChanged = false;
20547                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20548
20549                // If we haven't yet assigned the final cached adj
20550                // to the process, do that now.
20551                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20552                    switch (app.curProcState) {
20553                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20554                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20555                            // This process is a cached process holding activities...
20556                            // assign it the next cached value for that type, and then
20557                            // step that cached level.
20558                            app.curRawAdj = curCachedAdj;
20559                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20560                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20561                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20562                                    + ")");
20563                            if (curCachedAdj != nextCachedAdj) {
20564                                stepCached++;
20565                                if (stepCached >= cachedFactor) {
20566                                    stepCached = 0;
20567                                    curCachedAdj = nextCachedAdj;
20568                                    nextCachedAdj += 2;
20569                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20570                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20571                                    }
20572                                }
20573                            }
20574                            break;
20575                        default:
20576                            // For everything else, assign next empty cached process
20577                            // level and bump that up.  Note that this means that
20578                            // long-running services that have dropped down to the
20579                            // cached level will be treated as empty (since their process
20580                            // state is still as a service), which is what we want.
20581                            app.curRawAdj = curEmptyAdj;
20582                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20583                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20584                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20585                                    + ")");
20586                            if (curEmptyAdj != nextEmptyAdj) {
20587                                stepEmpty++;
20588                                if (stepEmpty >= emptyFactor) {
20589                                    stepEmpty = 0;
20590                                    curEmptyAdj = nextEmptyAdj;
20591                                    nextEmptyAdj += 2;
20592                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20593                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20594                                    }
20595                                }
20596                            }
20597                            break;
20598                    }
20599                }
20600
20601                applyOomAdjLocked(app, true, now, nowElapsed);
20602
20603                // Count the number of process types.
20604                switch (app.curProcState) {
20605                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20606                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20607                        mNumCachedHiddenProcs++;
20608                        numCached++;
20609                        if (numCached > cachedProcessLimit) {
20610                            app.kill("cached #" + numCached, true);
20611                        }
20612                        break;
20613                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20614                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20615                                && app.lastActivityTime < oldTime) {
20616                            app.kill("empty for "
20617                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20618                                    / 1000) + "s", true);
20619                        } else {
20620                            numEmpty++;
20621                            if (numEmpty > emptyProcessLimit) {
20622                                app.kill("empty #" + numEmpty, true);
20623                            }
20624                        }
20625                        break;
20626                    default:
20627                        mNumNonCachedProcs++;
20628                        break;
20629                }
20630
20631                if (app.isolated && app.services.size() <= 0) {
20632                    // If this is an isolated process, and there are no
20633                    // services running in it, then the process is no longer
20634                    // needed.  We agressively kill these because we can by
20635                    // definition not re-use the same process again, and it is
20636                    // good to avoid having whatever code was running in them
20637                    // left sitting around after no longer needed.
20638                    app.kill("isolated not needed", true);
20639                } else {
20640                    // Keeping this process, update its uid.
20641                    final UidRecord uidRec = app.uidRecord;
20642                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20643                        uidRec.curProcState = app.curProcState;
20644                    }
20645                }
20646
20647                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20648                        && !app.killedByAm) {
20649                    numTrimming++;
20650                }
20651            }
20652        }
20653
20654        mNumServiceProcs = mNewNumServiceProcs;
20655
20656        // Now determine the memory trimming level of background processes.
20657        // Unfortunately we need to start at the back of the list to do this
20658        // properly.  We only do this if the number of background apps we
20659        // are managing to keep around is less than half the maximum we desire;
20660        // if we are keeping a good number around, we'll let them use whatever
20661        // memory they want.
20662        final int numCachedAndEmpty = numCached + numEmpty;
20663        int memFactor;
20664        if (numCached <= ProcessList.TRIM_CACHED_APPS
20665                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20666            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20667                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20668            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20669                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20670            } else {
20671                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20672            }
20673        } else {
20674            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20675        }
20676        // We always allow the memory level to go up (better).  We only allow it to go
20677        // down if we are in a state where that is allowed, *and* the total number of processes
20678        // has gone down since last time.
20679        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20680                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20681                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20682        if (memFactor > mLastMemoryLevel) {
20683            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20684                memFactor = mLastMemoryLevel;
20685                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20686            }
20687        }
20688        if (memFactor != mLastMemoryLevel) {
20689            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20690        }
20691        mLastMemoryLevel = memFactor;
20692        mLastNumProcesses = mLruProcesses.size();
20693        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20694        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20695        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20696            if (mLowRamStartTime == 0) {
20697                mLowRamStartTime = now;
20698            }
20699            int step = 0;
20700            int fgTrimLevel;
20701            switch (memFactor) {
20702                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20703                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20704                    break;
20705                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20706                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20707                    break;
20708                default:
20709                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20710                    break;
20711            }
20712            int factor = numTrimming/3;
20713            int minFactor = 2;
20714            if (mHomeProcess != null) minFactor++;
20715            if (mPreviousProcess != null) minFactor++;
20716            if (factor < minFactor) factor = minFactor;
20717            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20718            for (int i=N-1; i>=0; i--) {
20719                ProcessRecord app = mLruProcesses.get(i);
20720                if (allChanged || app.procStateChanged) {
20721                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20722                    app.procStateChanged = false;
20723                }
20724                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20725                        && !app.killedByAm) {
20726                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20727                        try {
20728                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20729                                    "Trimming memory of " + app.processName + " to " + curLevel);
20730                            app.thread.scheduleTrimMemory(curLevel);
20731                        } catch (RemoteException e) {
20732                        }
20733                        if (false) {
20734                            // For now we won't do this; our memory trimming seems
20735                            // to be good enough at this point that destroying
20736                            // activities causes more harm than good.
20737                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20738                                    && app != mHomeProcess && app != mPreviousProcess) {
20739                                // Need to do this on its own message because the stack may not
20740                                // be in a consistent state at this point.
20741                                // For these apps we will also finish their activities
20742                                // to help them free memory.
20743                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20744                            }
20745                        }
20746                    }
20747                    app.trimMemoryLevel = curLevel;
20748                    step++;
20749                    if (step >= factor) {
20750                        step = 0;
20751                        switch (curLevel) {
20752                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20753                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20754                                break;
20755                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20756                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20757                                break;
20758                        }
20759                    }
20760                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20761                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20762                            && app.thread != null) {
20763                        try {
20764                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20765                                    "Trimming memory of heavy-weight " + app.processName
20766                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20767                            app.thread.scheduleTrimMemory(
20768                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20769                        } catch (RemoteException e) {
20770                        }
20771                    }
20772                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20773                } else {
20774                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20775                            || app.systemNoUi) && app.pendingUiClean) {
20776                        // If this application is now in the background and it
20777                        // had done UI, then give it the special trim level to
20778                        // have it free UI resources.
20779                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20780                        if (app.trimMemoryLevel < level && app.thread != null) {
20781                            try {
20782                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20783                                        "Trimming memory of bg-ui " + app.processName
20784                                        + " to " + level);
20785                                app.thread.scheduleTrimMemory(level);
20786                            } catch (RemoteException e) {
20787                            }
20788                        }
20789                        app.pendingUiClean = false;
20790                    }
20791                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20792                        try {
20793                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20794                                    "Trimming memory of fg " + app.processName
20795                                    + " to " + fgTrimLevel);
20796                            app.thread.scheduleTrimMemory(fgTrimLevel);
20797                        } catch (RemoteException e) {
20798                        }
20799                    }
20800                    app.trimMemoryLevel = fgTrimLevel;
20801                }
20802            }
20803        } else {
20804            if (mLowRamStartTime != 0) {
20805                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20806                mLowRamStartTime = 0;
20807            }
20808            for (int i=N-1; i>=0; i--) {
20809                ProcessRecord app = mLruProcesses.get(i);
20810                if (allChanged || app.procStateChanged) {
20811                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20812                    app.procStateChanged = false;
20813                }
20814                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20815                        || app.systemNoUi) && app.pendingUiClean) {
20816                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20817                            && app.thread != null) {
20818                        try {
20819                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20820                                    "Trimming memory of ui hidden " + app.processName
20821                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20822                            app.thread.scheduleTrimMemory(
20823                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20824                        } catch (RemoteException e) {
20825                        }
20826                    }
20827                    app.pendingUiClean = false;
20828                }
20829                app.trimMemoryLevel = 0;
20830            }
20831        }
20832
20833        if (mAlwaysFinishActivities) {
20834            // Need to do this on its own message because the stack may not
20835            // be in a consistent state at this point.
20836            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20837        }
20838
20839        if (allChanged) {
20840            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20841        }
20842
20843        // Update from any uid changes.
20844        for (int i=mActiveUids.size()-1; i>=0; i--) {
20845            final UidRecord uidRec = mActiveUids.valueAt(i);
20846            int uidChange = UidRecord.CHANGE_PROCSTATE;
20847            if (uidRec.setProcState != uidRec.curProcState) {
20848                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20849                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20850                        + " to " + uidRec.curProcState);
20851                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20852                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20853                        uidRec.lastBackgroundTime = nowElapsed;
20854                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20855                            // Note: the background settle time is in elapsed realtime, while
20856                            // the handler time base is uptime.  All this means is that we may
20857                            // stop background uids later than we had intended, but that only
20858                            // happens because the device was sleeping so we are okay anyway.
20859                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20860                        }
20861                    }
20862                } else {
20863                    if (uidRec.idle) {
20864                        uidChange = UidRecord.CHANGE_ACTIVE;
20865                        uidRec.idle = false;
20866                    }
20867                    uidRec.lastBackgroundTime = 0;
20868                }
20869                uidRec.setProcState = uidRec.curProcState;
20870                enqueueUidChangeLocked(uidRec, -1, uidChange);
20871                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20872            }
20873        }
20874
20875        if (mProcessStats.shouldWriteNowLocked(now)) {
20876            mHandler.post(new Runnable() {
20877                @Override public void run() {
20878                    synchronized (ActivityManagerService.this) {
20879                        mProcessStats.writeStateAsyncLocked();
20880                    }
20881                }
20882            });
20883        }
20884
20885        if (DEBUG_OOM_ADJ) {
20886            final long duration = SystemClock.uptimeMillis() - now;
20887            if (false) {
20888                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20889                        new RuntimeException("here").fillInStackTrace());
20890            } else {
20891                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20892            }
20893        }
20894    }
20895
20896    final void idleUids() {
20897        synchronized (this) {
20898            final long nowElapsed = SystemClock.elapsedRealtime();
20899            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20900            long nextTime = 0;
20901            for (int i=mActiveUids.size()-1; i>=0; i--) {
20902                final UidRecord uidRec = mActiveUids.valueAt(i);
20903                final long bgTime = uidRec.lastBackgroundTime;
20904                if (bgTime > 0 && !uidRec.idle) {
20905                    if (bgTime <= maxBgTime) {
20906                        uidRec.idle = true;
20907                        doStopUidLocked(uidRec.uid, uidRec);
20908                    } else {
20909                        if (nextTime == 0 || nextTime > bgTime) {
20910                            nextTime = bgTime;
20911                        }
20912                    }
20913                }
20914            }
20915            if (nextTime > 0) {
20916                mHandler.removeMessages(IDLE_UIDS_MSG);
20917                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20918                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20919            }
20920        }
20921    }
20922
20923    final void runInBackgroundDisabled(int uid) {
20924        synchronized (this) {
20925            UidRecord uidRec = mActiveUids.get(uid);
20926            if (uidRec != null) {
20927                // This uid is actually running...  should it be considered background now?
20928                if (uidRec.idle) {
20929                    doStopUidLocked(uidRec.uid, uidRec);
20930                }
20931            } else {
20932                // This uid isn't actually running...  still send a report about it being "stopped".
20933                doStopUidLocked(uid, null);
20934            }
20935        }
20936    }
20937
20938    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20939        mServices.stopInBackgroundLocked(uid);
20940        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20941    }
20942
20943    final void trimApplications() {
20944        synchronized (this) {
20945            int i;
20946
20947            // First remove any unused application processes whose package
20948            // has been removed.
20949            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20950                final ProcessRecord app = mRemovedProcesses.get(i);
20951                if (app.activities.size() == 0
20952                        && app.curReceiver == null && app.services.size() == 0) {
20953                    Slog.i(
20954                        TAG, "Exiting empty application process "
20955                        + app.toShortString() + " ("
20956                        + (app.thread != null ? app.thread.asBinder() : null)
20957                        + ")\n");
20958                    if (app.pid > 0 && app.pid != MY_PID) {
20959                        app.kill("empty", false);
20960                    } else {
20961                        try {
20962                            app.thread.scheduleExit();
20963                        } catch (Exception e) {
20964                            // Ignore exceptions.
20965                        }
20966                    }
20967                    cleanUpApplicationRecordLocked(app, false, true, -1);
20968                    mRemovedProcesses.remove(i);
20969
20970                    if (app.persistent) {
20971                        addAppLocked(app.info, false, null /* ABI override */);
20972                    }
20973                }
20974            }
20975
20976            // Now update the oom adj for all processes.
20977            updateOomAdjLocked();
20978        }
20979    }
20980
20981    /** This method sends the specified signal to each of the persistent apps */
20982    public void signalPersistentProcesses(int sig) throws RemoteException {
20983        if (sig != Process.SIGNAL_USR1) {
20984            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20985        }
20986
20987        synchronized (this) {
20988            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20989                    != PackageManager.PERMISSION_GRANTED) {
20990                throw new SecurityException("Requires permission "
20991                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20992            }
20993
20994            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20995                ProcessRecord r = mLruProcesses.get(i);
20996                if (r.thread != null && r.persistent) {
20997                    Process.sendSignal(r.pid, sig);
20998                }
20999            }
21000        }
21001    }
21002
21003    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21004        if (proc == null || proc == mProfileProc) {
21005            proc = mProfileProc;
21006            profileType = mProfileType;
21007            clearProfilerLocked();
21008        }
21009        if (proc == null) {
21010            return;
21011        }
21012        try {
21013            proc.thread.profilerControl(false, null, profileType);
21014        } catch (RemoteException e) {
21015            throw new IllegalStateException("Process disappeared");
21016        }
21017    }
21018
21019    private void clearProfilerLocked() {
21020        if (mProfileFd != null) {
21021            try {
21022                mProfileFd.close();
21023            } catch (IOException e) {
21024            }
21025        }
21026        mProfileApp = null;
21027        mProfileProc = null;
21028        mProfileFile = null;
21029        mProfileType = 0;
21030        mAutoStopProfiler = false;
21031        mSamplingInterval = 0;
21032    }
21033
21034    public boolean profileControl(String process, int userId, boolean start,
21035            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21036
21037        try {
21038            synchronized (this) {
21039                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21040                // its own permission.
21041                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21042                        != PackageManager.PERMISSION_GRANTED) {
21043                    throw new SecurityException("Requires permission "
21044                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21045                }
21046
21047                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21048                    throw new IllegalArgumentException("null profile info or fd");
21049                }
21050
21051                ProcessRecord proc = null;
21052                if (process != null) {
21053                    proc = findProcessLocked(process, userId, "profileControl");
21054                }
21055
21056                if (start && (proc == null || proc.thread == null)) {
21057                    throw new IllegalArgumentException("Unknown process: " + process);
21058                }
21059
21060                if (start) {
21061                    stopProfilerLocked(null, 0);
21062                    setProfileApp(proc.info, proc.processName, profilerInfo);
21063                    mProfileProc = proc;
21064                    mProfileType = profileType;
21065                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21066                    try {
21067                        fd = fd.dup();
21068                    } catch (IOException e) {
21069                        fd = null;
21070                    }
21071                    profilerInfo.profileFd = fd;
21072                    proc.thread.profilerControl(start, profilerInfo, profileType);
21073                    fd = null;
21074                    mProfileFd = null;
21075                } else {
21076                    stopProfilerLocked(proc, profileType);
21077                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21078                        try {
21079                            profilerInfo.profileFd.close();
21080                        } catch (IOException e) {
21081                        }
21082                    }
21083                }
21084
21085                return true;
21086            }
21087        } catch (RemoteException e) {
21088            throw new IllegalStateException("Process disappeared");
21089        } finally {
21090            if (profilerInfo != null && profilerInfo.profileFd != null) {
21091                try {
21092                    profilerInfo.profileFd.close();
21093                } catch (IOException e) {
21094                }
21095            }
21096        }
21097    }
21098
21099    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21100        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21101                userId, true, ALLOW_FULL_ONLY, callName, null);
21102        ProcessRecord proc = null;
21103        try {
21104            int pid = Integer.parseInt(process);
21105            synchronized (mPidsSelfLocked) {
21106                proc = mPidsSelfLocked.get(pid);
21107            }
21108        } catch (NumberFormatException e) {
21109        }
21110
21111        if (proc == null) {
21112            ArrayMap<String, SparseArray<ProcessRecord>> all
21113                    = mProcessNames.getMap();
21114            SparseArray<ProcessRecord> procs = all.get(process);
21115            if (procs != null && procs.size() > 0) {
21116                proc = procs.valueAt(0);
21117                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21118                    for (int i=1; i<procs.size(); i++) {
21119                        ProcessRecord thisProc = procs.valueAt(i);
21120                        if (thisProc.userId == userId) {
21121                            proc = thisProc;
21122                            break;
21123                        }
21124                    }
21125                }
21126            }
21127        }
21128
21129        return proc;
21130    }
21131
21132    public boolean dumpHeap(String process, int userId, boolean managed,
21133            String path, ParcelFileDescriptor fd) throws RemoteException {
21134
21135        try {
21136            synchronized (this) {
21137                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21138                // its own permission (same as profileControl).
21139                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21140                        != PackageManager.PERMISSION_GRANTED) {
21141                    throw new SecurityException("Requires permission "
21142                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21143                }
21144
21145                if (fd == null) {
21146                    throw new IllegalArgumentException("null fd");
21147                }
21148
21149                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21150                if (proc == null || proc.thread == null) {
21151                    throw new IllegalArgumentException("Unknown process: " + process);
21152                }
21153
21154                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21155                if (!isDebuggable) {
21156                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21157                        throw new SecurityException("Process not debuggable: " + proc);
21158                    }
21159                }
21160
21161                proc.thread.dumpHeap(managed, path, fd);
21162                fd = null;
21163                return true;
21164            }
21165        } catch (RemoteException e) {
21166            throw new IllegalStateException("Process disappeared");
21167        } finally {
21168            if (fd != null) {
21169                try {
21170                    fd.close();
21171                } catch (IOException e) {
21172                }
21173            }
21174        }
21175    }
21176
21177    @Override
21178    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21179            String reportPackage) {
21180        if (processName != null) {
21181            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21182                    "setDumpHeapDebugLimit()");
21183        } else {
21184            synchronized (mPidsSelfLocked) {
21185                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21186                if (proc == null) {
21187                    throw new SecurityException("No process found for calling pid "
21188                            + Binder.getCallingPid());
21189                }
21190                if (!Build.IS_DEBUGGABLE
21191                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21192                    throw new SecurityException("Not running a debuggable build");
21193                }
21194                processName = proc.processName;
21195                uid = proc.uid;
21196                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21197                    throw new SecurityException("Package " + reportPackage + " is not running in "
21198                            + proc);
21199                }
21200            }
21201        }
21202        synchronized (this) {
21203            if (maxMemSize > 0) {
21204                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21205            } else {
21206                if (uid != 0) {
21207                    mMemWatchProcesses.remove(processName, uid);
21208                } else {
21209                    mMemWatchProcesses.getMap().remove(processName);
21210                }
21211            }
21212        }
21213    }
21214
21215    @Override
21216    public void dumpHeapFinished(String path) {
21217        synchronized (this) {
21218            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21219                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21220                        + " does not match last pid " + mMemWatchDumpPid);
21221                return;
21222            }
21223            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21224                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21225                        + " does not match last path " + mMemWatchDumpFile);
21226                return;
21227            }
21228            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21229            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21230        }
21231    }
21232
21233    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21234    public void monitor() {
21235        synchronized (this) { }
21236    }
21237
21238    void onCoreSettingsChange(Bundle settings) {
21239        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21240            ProcessRecord processRecord = mLruProcesses.get(i);
21241            try {
21242                if (processRecord.thread != null) {
21243                    processRecord.thread.setCoreSettings(settings);
21244                }
21245            } catch (RemoteException re) {
21246                /* ignore */
21247            }
21248        }
21249    }
21250
21251    // Multi-user methods
21252
21253    /**
21254     * Start user, if its not already running, but don't bring it to foreground.
21255     */
21256    @Override
21257    public boolean startUserInBackground(final int userId) {
21258        return mUserController.startUser(userId, /* foreground */ false);
21259    }
21260
21261    @Override
21262    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21263        return mUserController.unlockUser(userId, token, secret, listener);
21264    }
21265
21266    @Override
21267    public boolean switchUser(final int targetUserId) {
21268        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21269        UserInfo currentUserInfo;
21270        UserInfo targetUserInfo;
21271        synchronized (this) {
21272            int currentUserId = mUserController.getCurrentUserIdLocked();
21273            currentUserInfo = mUserController.getUserInfo(currentUserId);
21274            targetUserInfo = mUserController.getUserInfo(targetUserId);
21275            if (targetUserInfo == null) {
21276                Slog.w(TAG, "No user info for user #" + targetUserId);
21277                return false;
21278            }
21279            if (!targetUserInfo.supportsSwitchTo()) {
21280                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21281                return false;
21282            }
21283            if (targetUserInfo.isManagedProfile()) {
21284                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21285                return false;
21286            }
21287            mUserController.setTargetUserIdLocked(targetUserId);
21288        }
21289        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21290        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21291        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21292        return true;
21293    }
21294
21295    void scheduleStartProfilesLocked() {
21296        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21297            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21298                    DateUtils.SECOND_IN_MILLIS);
21299        }
21300    }
21301
21302    @Override
21303    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21304        return mUserController.stopUser(userId, force, callback);
21305    }
21306
21307    @Override
21308    public UserInfo getCurrentUser() {
21309        return mUserController.getCurrentUser();
21310    }
21311
21312    @Override
21313    public boolean isUserRunning(int userId, int flags) {
21314        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21315                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21316            String msg = "Permission Denial: isUserRunning() from pid="
21317                    + Binder.getCallingPid()
21318                    + ", uid=" + Binder.getCallingUid()
21319                    + " requires " + INTERACT_ACROSS_USERS;
21320            Slog.w(TAG, msg);
21321            throw new SecurityException(msg);
21322        }
21323        synchronized (this) {
21324            return mUserController.isUserRunningLocked(userId, flags);
21325        }
21326    }
21327
21328    @Override
21329    public int[] getRunningUserIds() {
21330        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21331                != PackageManager.PERMISSION_GRANTED) {
21332            String msg = "Permission Denial: isUserRunning() from pid="
21333                    + Binder.getCallingPid()
21334                    + ", uid=" + Binder.getCallingUid()
21335                    + " requires " + INTERACT_ACROSS_USERS;
21336            Slog.w(TAG, msg);
21337            throw new SecurityException(msg);
21338        }
21339        synchronized (this) {
21340            return mUserController.getStartedUserArrayLocked();
21341        }
21342    }
21343
21344    @Override
21345    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21346        mUserController.registerUserSwitchObserver(observer);
21347    }
21348
21349    @Override
21350    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21351        mUserController.unregisterUserSwitchObserver(observer);
21352    }
21353
21354    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21355        if (info == null) return null;
21356        ApplicationInfo newInfo = new ApplicationInfo(info);
21357        newInfo.initForUser(userId);
21358        return newInfo;
21359    }
21360
21361    public boolean isUserStopped(int userId) {
21362        synchronized (this) {
21363            return mUserController.getStartedUserStateLocked(userId) == null;
21364        }
21365    }
21366
21367    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21368        if (aInfo == null
21369                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21370            return aInfo;
21371        }
21372
21373        ActivityInfo info = new ActivityInfo(aInfo);
21374        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21375        return info;
21376    }
21377
21378    private boolean processSanityChecksLocked(ProcessRecord process) {
21379        if (process == null || process.thread == null) {
21380            return false;
21381        }
21382
21383        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21384        if (!isDebuggable) {
21385            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21386                return false;
21387            }
21388        }
21389
21390        return true;
21391    }
21392
21393    public boolean startBinderTracking() throws RemoteException {
21394        synchronized (this) {
21395            mBinderTransactionTrackingEnabled = true;
21396            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21397            // permission (same as profileControl).
21398            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21399                    != PackageManager.PERMISSION_GRANTED) {
21400                throw new SecurityException("Requires permission "
21401                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21402            }
21403
21404            for (int i = 0; i < mLruProcesses.size(); i++) {
21405                ProcessRecord process = mLruProcesses.get(i);
21406                if (!processSanityChecksLocked(process)) {
21407                    continue;
21408                }
21409                try {
21410                    process.thread.startBinderTracking();
21411                } catch (RemoteException e) {
21412                    Log.v(TAG, "Process disappared");
21413                }
21414            }
21415            return true;
21416        }
21417    }
21418
21419    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21420        try {
21421            synchronized (this) {
21422                mBinderTransactionTrackingEnabled = false;
21423                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21424                // permission (same as profileControl).
21425                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21426                        != PackageManager.PERMISSION_GRANTED) {
21427                    throw new SecurityException("Requires permission "
21428                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21429                }
21430
21431                if (fd == null) {
21432                    throw new IllegalArgumentException("null fd");
21433                }
21434
21435                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21436                pw.println("Binder transaction traces for all processes.\n");
21437                for (ProcessRecord process : mLruProcesses) {
21438                    if (!processSanityChecksLocked(process)) {
21439                        continue;
21440                    }
21441
21442                    pw.println("Traces for process: " + process.processName);
21443                    pw.flush();
21444                    try {
21445                        TransferPipe tp = new TransferPipe();
21446                        try {
21447                            process.thread.stopBinderTrackingAndDump(
21448                                    tp.getWriteFd().getFileDescriptor());
21449                            tp.go(fd.getFileDescriptor());
21450                        } finally {
21451                            tp.kill();
21452                        }
21453                    } catch (IOException e) {
21454                        pw.println("Failure while dumping IPC traces from " + process +
21455                                ".  Exception: " + e);
21456                        pw.flush();
21457                    } catch (RemoteException e) {
21458                        pw.println("Got a RemoteException while dumping IPC traces from " +
21459                                process + ".  Exception: " + e);
21460                        pw.flush();
21461                    }
21462                }
21463                fd = null;
21464                return true;
21465            }
21466        } finally {
21467            if (fd != null) {
21468                try {
21469                    fd.close();
21470                } catch (IOException e) {
21471                }
21472            }
21473        }
21474    }
21475
21476    private final class LocalService extends ActivityManagerInternal {
21477        @Override
21478        public void onWakefulnessChanged(int wakefulness) {
21479            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21480        }
21481
21482        @Override
21483        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21484                String processName, String abiOverride, int uid, Runnable crashHandler) {
21485            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21486                    processName, abiOverride, uid, crashHandler);
21487        }
21488
21489        @Override
21490        public SleepToken acquireSleepToken(String tag) {
21491            Preconditions.checkNotNull(tag);
21492
21493            ComponentName requestedVrService = null;
21494            ComponentName callingVrActivity = null;
21495            int userId = -1;
21496            synchronized (ActivityManagerService.this) {
21497                if (mFocusedActivity != null) {
21498                    requestedVrService = mFocusedActivity.requestedVrComponent;
21499                    callingVrActivity = mFocusedActivity.info.getComponentName();
21500                    userId = mFocusedActivity.userId;
21501                }
21502            }
21503
21504            if (requestedVrService != null) {
21505                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21506            }
21507
21508            synchronized (ActivityManagerService.this) {
21509                SleepTokenImpl token = new SleepTokenImpl(tag);
21510                mSleepTokens.add(token);
21511                updateSleepIfNeededLocked();
21512                return token;
21513            }
21514        }
21515
21516        @Override
21517        public ComponentName getHomeActivityForUser(int userId) {
21518            synchronized (ActivityManagerService.this) {
21519                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21520                return homeActivity == null ? null : homeActivity.realActivity;
21521            }
21522        }
21523
21524        @Override
21525        public void onUserRemoved(int userId) {
21526            synchronized (ActivityManagerService.this) {
21527                ActivityManagerService.this.onUserStoppedLocked(userId);
21528            }
21529        }
21530
21531        @Override
21532        public void onLocalVoiceInteractionStarted(IBinder activity,
21533                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21534            synchronized (ActivityManagerService.this) {
21535                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21536                        voiceSession, voiceInteractor);
21537            }
21538        }
21539
21540        @Override
21541        public void notifyStartingWindowDrawn() {
21542            synchronized (ActivityManagerService.this) {
21543                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21544            }
21545        }
21546
21547        @Override
21548        public void notifyAppTransitionStarting(int reason) {
21549            synchronized (ActivityManagerService.this) {
21550                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21551            }
21552        }
21553
21554        @Override
21555        public void notifyAppTransitionFinished() {
21556            synchronized (ActivityManagerService.this) {
21557                mStackSupervisor.notifyAppTransitionDone();
21558            }
21559        }
21560
21561        @Override
21562        public void notifyAppTransitionCancelled() {
21563            synchronized (ActivityManagerService.this) {
21564                mStackSupervisor.notifyAppTransitionDone();
21565            }
21566        }
21567
21568        @Override
21569        public List<IBinder> getTopVisibleActivities() {
21570            synchronized (ActivityManagerService.this) {
21571                return mStackSupervisor.getTopVisibleActivities();
21572            }
21573        }
21574
21575        @Override
21576        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21577            synchronized (ActivityManagerService.this) {
21578                mStackSupervisor.setDockedStackMinimized(minimized);
21579            }
21580        }
21581
21582        @Override
21583        public void killForegroundAppsForUser(int userHandle) {
21584            synchronized (ActivityManagerService.this) {
21585                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21586                final int NP = mProcessNames.getMap().size();
21587                for (int ip = 0; ip < NP; ip++) {
21588                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21589                    final int NA = apps.size();
21590                    for (int ia = 0; ia < NA; ia++) {
21591                        final ProcessRecord app = apps.valueAt(ia);
21592                        if (app.persistent) {
21593                            // We don't kill persistent processes.
21594                            continue;
21595                        }
21596                        if (app.removed) {
21597                            procs.add(app);
21598                        } else if (app.userId == userHandle && app.foregroundActivities) {
21599                            app.removed = true;
21600                            procs.add(app);
21601                        }
21602                    }
21603                }
21604
21605                final int N = procs.size();
21606                for (int i = 0; i < N; i++) {
21607                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21608                }
21609            }
21610        }
21611
21612        @Override
21613        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21614            if (!(target instanceof PendingIntentRecord)) {
21615                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21616                return;
21617            }
21618            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21619        }
21620    }
21621
21622    private final class SleepTokenImpl extends SleepToken {
21623        private final String mTag;
21624        private final long mAcquireTime;
21625
21626        public SleepTokenImpl(String tag) {
21627            mTag = tag;
21628            mAcquireTime = SystemClock.uptimeMillis();
21629        }
21630
21631        @Override
21632        public void release() {
21633            synchronized (ActivityManagerService.this) {
21634                if (mSleepTokens.remove(this)) {
21635                    updateSleepIfNeededLocked();
21636                }
21637            }
21638        }
21639
21640        @Override
21641        public String toString() {
21642            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21643        }
21644    }
21645
21646    /**
21647     * An implementation of IAppTask, that allows an app to manage its own tasks via
21648     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21649     * only the process that calls getAppTasks() can call the AppTask methods.
21650     */
21651    class AppTaskImpl extends IAppTask.Stub {
21652        private int mTaskId;
21653        private int mCallingUid;
21654
21655        public AppTaskImpl(int taskId, int callingUid) {
21656            mTaskId = taskId;
21657            mCallingUid = callingUid;
21658        }
21659
21660        private void checkCaller() {
21661            if (mCallingUid != Binder.getCallingUid()) {
21662                throw new SecurityException("Caller " + mCallingUid
21663                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21664            }
21665        }
21666
21667        @Override
21668        public void finishAndRemoveTask() {
21669            checkCaller();
21670
21671            synchronized (ActivityManagerService.this) {
21672                long origId = Binder.clearCallingIdentity();
21673                try {
21674                    // We remove the task from recents to preserve backwards
21675                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21676                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21677                    }
21678                } finally {
21679                    Binder.restoreCallingIdentity(origId);
21680                }
21681            }
21682        }
21683
21684        @Override
21685        public ActivityManager.RecentTaskInfo getTaskInfo() {
21686            checkCaller();
21687
21688            synchronized (ActivityManagerService.this) {
21689                long origId = Binder.clearCallingIdentity();
21690                try {
21691                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21692                    if (tr == null) {
21693                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21694                    }
21695                    return createRecentTaskInfoFromTaskRecord(tr);
21696                } finally {
21697                    Binder.restoreCallingIdentity(origId);
21698                }
21699            }
21700        }
21701
21702        @Override
21703        public void moveToFront() {
21704            checkCaller();
21705            // Will bring task to front if it already has a root activity.
21706            final long origId = Binder.clearCallingIdentity();
21707            try {
21708                synchronized (this) {
21709                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21710                }
21711            } finally {
21712                Binder.restoreCallingIdentity(origId);
21713            }
21714        }
21715
21716        @Override
21717        public int startActivity(IBinder whoThread, String callingPackage,
21718                Intent intent, String resolvedType, Bundle bOptions) {
21719            checkCaller();
21720
21721            int callingUser = UserHandle.getCallingUserId();
21722            TaskRecord tr;
21723            IApplicationThread appThread;
21724            synchronized (ActivityManagerService.this) {
21725                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21726                if (tr == null) {
21727                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21728                }
21729                appThread = ApplicationThreadNative.asInterface(whoThread);
21730                if (appThread == null) {
21731                    throw new IllegalArgumentException("Bad app thread " + appThread);
21732                }
21733            }
21734            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21735                    resolvedType, null, null, null, null, 0, 0, null, null,
21736                    null, bOptions, false, callingUser, null, tr);
21737        }
21738
21739        @Override
21740        public void setExcludeFromRecents(boolean exclude) {
21741            checkCaller();
21742
21743            synchronized (ActivityManagerService.this) {
21744                long origId = Binder.clearCallingIdentity();
21745                try {
21746                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21747                    if (tr == null) {
21748                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21749                    }
21750                    Intent intent = tr.getBaseIntent();
21751                    if (exclude) {
21752                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21753                    } else {
21754                        intent.setFlags(intent.getFlags()
21755                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21756                    }
21757                } finally {
21758                    Binder.restoreCallingIdentity(origId);
21759                }
21760            }
21761        }
21762    }
21763
21764    /**
21765     * Kill processes for the user with id userId and that depend on the package named packageName
21766     */
21767    @Override
21768    public void killPackageDependents(String packageName, int userId) {
21769        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21770        if (packageName == null) {
21771            throw new NullPointerException(
21772                    "Cannot kill the dependents of a package without its name.");
21773        }
21774
21775        long callingId = Binder.clearCallingIdentity();
21776        IPackageManager pm = AppGlobals.getPackageManager();
21777        int pkgUid = -1;
21778        try {
21779            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21780        } catch (RemoteException e) {
21781        }
21782        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21783            throw new IllegalArgumentException(
21784                    "Cannot kill dependents of non-existing package " + packageName);
21785        }
21786        try {
21787            synchronized(this) {
21788                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21789                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21790                        "dep: " + packageName);
21791            }
21792        } finally {
21793            Binder.restoreCallingIdentity(callingId);
21794        }
21795    }
21796}
21797