ActivityManagerService.java revision bc02a3901dea52d236dd855722191155156cb856
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.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.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_UNAWARE;
271import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
272import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
273import static android.content.pm.PackageManager.PERMISSION_GRANTED;
274import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
275import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
276import static android.provider.Settings.Global.DEBUG_APP;
277import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
278import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
280import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
281import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
282import static android.provider.Settings.System.FONT_SCALE;
283import static com.android.internal.util.XmlUtils.readBooleanAttribute;
284import static com.android.internal.util.XmlUtils.readIntAttribute;
285import static com.android.internal.util.XmlUtils.readLongAttribute;
286import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
287import static com.android.internal.util.XmlUtils.writeIntAttribute;
288import static com.android.internal.util.XmlUtils.writeLongAttribute;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
346import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
348import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
349import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
350import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
351import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
352import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
353import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
354import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
355import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
356import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
359import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
361import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
364import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
365import static org.xmlpull.v1.XmlPullParser.START_TAG;
366
367public final class ActivityManagerService extends ActivityManagerNative
368        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
369
370    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
371    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
372    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
373    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
374    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
375    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
376    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
377    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
378    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
379    private static final String TAG_LRU = TAG + POSTFIX_LRU;
380    private static final String TAG_MU = TAG + POSTFIX_MU;
381    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
382    private static final String TAG_POWER = TAG + POSTFIX_POWER;
383    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
384    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
385    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
386    private static final String TAG_PSS = TAG + POSTFIX_PSS;
387    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
388    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
389    private static final String TAG_STACK = TAG + POSTFIX_STACK;
390    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
391    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
392    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
393    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
394    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
395
396    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
397    // here so that while the job scheduler can depend on AMS, the other way around
398    // need not be the case.
399    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
400
401    /** Control over CPU and battery monitoring */
402    // write battery stats every 30 minutes.
403    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
404    static final boolean MONITOR_CPU_USAGE = true;
405    // don't sample cpu less than every 5 seconds.
406    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
407    // wait possibly forever for next cpu sample.
408    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
409    static final boolean MONITOR_THREAD_CPU_USAGE = false;
410
411    // The flags that are set for all calls we make to the package manager.
412    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
413
414    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
415
416    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
417
418    // Amount of time after a call to stopAppSwitches() during which we will
419    // prevent further untrusted switches from happening.
420    static final long APP_SWITCH_DELAY_TIME = 5*1000;
421
422    // How long we wait for a launched process to attach to the activity manager
423    // before we decide it's never going to come up for real.
424    static final int PROC_START_TIMEOUT = 10*1000;
425    // How long we wait for an attached process to publish its content providers
426    // before we decide it must be hung.
427    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
428
429    // How long we will retain processes hosting content providers in the "last activity"
430    // state before allowing them to drop down to the regular cached LRU list.  This is
431    // to avoid thrashing of provider processes under low memory situations.
432    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
433
434    // How long we wait for a launched process to attach to the activity manager
435    // before we decide it's never going to come up for real, when the process was
436    // started with a wrapper for instrumentation (such as Valgrind) because it
437    // could take much longer than usual.
438    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
439
440    // How long to wait after going idle before forcing apps to GC.
441    static final int GC_TIMEOUT = 5*1000;
442
443    // The minimum amount of time between successive GC requests for a process.
444    static final int GC_MIN_INTERVAL = 60*1000;
445
446    // The minimum amount of time between successive PSS requests for a process.
447    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
448
449    // The minimum amount of time between successive PSS requests for a process
450    // when the request is due to the memory state being lowered.
451    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
452
453    // The rate at which we check for apps using excessive power -- 15 mins.
454    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
455
456    // The minimum sample duration we will allow before deciding we have
457    // enough data on wake locks to start killing things.
458    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
459
460    // The minimum sample duration we will allow before deciding we have
461    // enough data on CPU usage to start killing things.
462    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
463
464    // How long we allow a receiver to run before giving up on it.
465    static final int BROADCAST_FG_TIMEOUT = 10*1000;
466    static final int BROADCAST_BG_TIMEOUT = 60*1000;
467
468    // How long we wait until we timeout on key dispatching.
469    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
470
471    // How long we wait until we timeout on key dispatching during instrumentation.
472    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
473
474    // This is the amount of time an app needs to be running a foreground service before
475    // we will consider it to be doing interaction for usage stats.
476    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
477
478    // Maximum amount of time we will allow to elapse before re-reporting usage stats
479    // interaction with foreground processes.
480    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
481
482    // This is the amount of time we allow an app to settle after it goes into the background,
483    // before we start restricting what it can do.
484    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
485
486    // How long to wait in getAssistContextExtras for the activity and foreground services
487    // to respond with the result.
488    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
489
490    // How long top wait when going through the modern assist (which doesn't need to block
491    // on getting this result before starting to launch its UI).
492    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
493
494    // Maximum number of persisted Uri grants a package is allowed
495    static final int MAX_PERSISTED_URI_GRANTS = 128;
496
497    static final int MY_PID = Process.myPid();
498
499    static final String[] EMPTY_STRING_ARRAY = new String[0];
500
501    // How many bytes to write into the dropbox log before truncating
502    static final int DROPBOX_MAX_SIZE = 256 * 1024;
503
504    // Access modes for handleIncomingUser.
505    static final int ALLOW_NON_FULL = 0;
506    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
507    static final int ALLOW_FULL_ONLY = 2;
508
509    // Delay in notifying task stack change listeners (in millis)
510    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
511
512    // Necessary ApplicationInfo flags to mark an app as persistent
513    private static final int PERSISTENT_MASK =
514            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
515
516    // Intent sent when remote bugreport collection has been completed
517    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
518            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
519
520    // Delay to disable app launch boost
521    static final int APP_BOOST_MESSAGE_DELAY = 3000;
522    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
523    static final int APP_BOOST_TIMEOUT = 2500;
524
525    // Used to indicate that a task is removed it should also be removed from recents.
526    private static final boolean REMOVE_FROM_RECENTS = true;
527    // Used to indicate that an app transition should be animated.
528    static final boolean ANIMATE = true;
529
530    // Determines whether to take full screen screenshots
531    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
532    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
533
534    private static native int nativeMigrateToBoost();
535    private static native int nativeMigrateFromBoost();
536    private boolean mIsBoosted = false;
537    private long mBoostStartTime = 0;
538
539    /** All system services */
540    SystemServiceManager mSystemServiceManager;
541
542    private Installer mInstaller;
543
544    /** Run all ActivityStacks through this */
545    final ActivityStackSupervisor mStackSupervisor;
546
547    final ActivityStarter mActivityStarter;
548
549    /** Task stack change listeners. */
550    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
551            new RemoteCallbackList<ITaskStackListener>();
552
553    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
554
555    public IntentFirewall mIntentFirewall;
556
557    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
558    // default actuion automatically.  Important for devices without direct input
559    // devices.
560    private boolean mShowDialogs = true;
561    private boolean mInVrMode = false;
562
563    BroadcastQueue mFgBroadcastQueue;
564    BroadcastQueue mBgBroadcastQueue;
565    // Convenient for easy iteration over the queues. Foreground is first
566    // so that dispatch of foreground broadcasts gets precedence.
567    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
568
569    BroadcastStats mLastBroadcastStats;
570    BroadcastStats mCurBroadcastStats;
571
572    BroadcastQueue broadcastQueueForIntent(Intent intent) {
573        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
574        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
575                "Broadcast intent " + intent + " on "
576                + (isFg ? "foreground" : "background") + " queue");
577        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
578    }
579
580    /**
581     * Activity we have told the window manager to have key focus.
582     */
583    ActivityRecord mFocusedActivity = null;
584
585    /**
586     * User id of the last activity mFocusedActivity was set to.
587     */
588    private int mLastFocusedUserId;
589
590    /**
591     * If non-null, we are tracking the time the user spends in the currently focused app.
592     */
593    private AppTimeTracker mCurAppTimeTracker;
594
595    /**
596     * List of intents that were used to start the most recent tasks.
597     */
598    final RecentTasks mRecentTasks;
599
600    /**
601     * For addAppTask: cached of the last activity component that was added.
602     */
603    ComponentName mLastAddedTaskComponent;
604
605    /**
606     * For addAppTask: cached of the last activity uid that was added.
607     */
608    int mLastAddedTaskUid;
609
610    /**
611     * For addAppTask: cached of the last ActivityInfo that was added.
612     */
613    ActivityInfo mLastAddedTaskActivity;
614
615    /**
616     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
617     */
618    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
619
620    /**
621     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
622     */
623    String mDeviceOwnerName;
624
625    final UserController mUserController;
626
627    final AppErrors mAppErrors;
628
629    boolean mDoingSetFocusedActivity;
630
631    public boolean canShowErrorDialogs() {
632        return mShowDialogs && !mSleeping && !mShuttingDown;
633    }
634
635    // it's a semaphore; boost when 0->1, reset when 1->0
636    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
637        @Override protected Integer initialValue() {
638            return 0;
639        }
640    };
641
642    static void boostPriorityForLockedSection() {
643        if (sIsBoosted.get() == 0) {
644            // boost to prio 118 while holding a global lock
645            Process.setThreadPriority(Process.myTid(), -2);
646            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
647        }
648        int cur = sIsBoosted.get();
649        sIsBoosted.set(cur + 1);
650    }
651
652    static void resetPriorityAfterLockedSection() {
653        sIsBoosted.set(sIsBoosted.get() - 1);
654        if (sIsBoosted.get() == 0) {
655            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
656            Process.setThreadPriority(Process.myTid(), 0);
657        }
658    }
659    public class PendingAssistExtras extends Binder implements Runnable {
660        public final ActivityRecord activity;
661        public final Bundle extras;
662        public final Intent intent;
663        public final String hint;
664        public final IResultReceiver receiver;
665        public final int userHandle;
666        public boolean haveResult = false;
667        public Bundle result = null;
668        public AssistStructure structure = null;
669        public AssistContent content = null;
670        public Bundle receiverExtras;
671
672        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
673                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
674            activity = _activity;
675            extras = _extras;
676            intent = _intent;
677            hint = _hint;
678            receiver = _receiver;
679            receiverExtras = _receiverExtras;
680            userHandle = _userHandle;
681        }
682        @Override
683        public void run() {
684            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
685            synchronized (this) {
686                haveResult = true;
687                notifyAll();
688            }
689            pendingAssistExtrasTimedOut(this);
690        }
691    }
692
693    final ArrayList<PendingAssistExtras> mPendingAssistExtras
694            = new ArrayList<PendingAssistExtras>();
695
696    /**
697     * Process management.
698     */
699    final ProcessList mProcessList = new ProcessList();
700
701    /**
702     * All of the applications we currently have running organized by name.
703     * The keys are strings of the application package name (as
704     * returned by the package manager), and the keys are ApplicationRecord
705     * objects.
706     */
707    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
708
709    /**
710     * Tracking long-term execution of processes to look for abuse and other
711     * bad app behavior.
712     */
713    final ProcessStatsService mProcessStats;
714
715    /**
716     * The currently running isolated processes.
717     */
718    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
719
720    /**
721     * Counter for assigning isolated process uids, to avoid frequently reusing the
722     * same ones.
723     */
724    int mNextIsolatedProcessUid = 0;
725
726    /**
727     * The currently running heavy-weight process, if any.
728     */
729    ProcessRecord mHeavyWeightProcess = null;
730
731    /**
732     * All of the processes we currently have running organized by pid.
733     * The keys are the pid running the application.
734     *
735     * <p>NOTE: This object is protected by its own lock, NOT the global
736     * activity manager lock!
737     */
738    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
739
740    /**
741     * All of the processes that have been forced to be foreground.  The key
742     * is the pid of the caller who requested it (we hold a death
743     * link on it).
744     */
745    abstract class ForegroundToken implements IBinder.DeathRecipient {
746        int pid;
747        IBinder token;
748    }
749    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
750
751    /**
752     * List of records for processes that someone had tried to start before the
753     * system was ready.  We don't start them at that point, but ensure they
754     * are started by the time booting is complete.
755     */
756    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
757
758    /**
759     * List of persistent applications that are in the process
760     * of being started.
761     */
762    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
763
764    /**
765     * Processes that are being forcibly torn down.
766     */
767    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
768
769    /**
770     * List of running applications, sorted by recent usage.
771     * The first entry in the list is the least recently used.
772     */
773    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
774
775    /**
776     * Where in mLruProcesses that the processes hosting activities start.
777     */
778    int mLruProcessActivityStart = 0;
779
780    /**
781     * Where in mLruProcesses that the processes hosting services start.
782     * This is after (lower index) than mLruProcessesActivityStart.
783     */
784    int mLruProcessServiceStart = 0;
785
786    /**
787     * List of processes that should gc as soon as things are idle.
788     */
789    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
790
791    /**
792     * Processes we want to collect PSS data from.
793     */
794    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
795
796    private boolean mBinderTransactionTrackingEnabled = false;
797
798    /**
799     * Last time we requested PSS data of all processes.
800     */
801    long mLastFullPssTime = SystemClock.uptimeMillis();
802
803    /**
804     * If set, the next time we collect PSS data we should do a full collection
805     * with data from native processes and the kernel.
806     */
807    boolean mFullPssPending = false;
808
809    /**
810     * This is the process holding what we currently consider to be
811     * the "home" activity.
812     */
813    ProcessRecord mHomeProcess;
814
815    /**
816     * This is the process holding the activity the user last visited that
817     * is in a different process from the one they are currently in.
818     */
819    ProcessRecord mPreviousProcess;
820
821    /**
822     * The time at which the previous process was last visible.
823     */
824    long mPreviousProcessVisibleTime;
825
826    /**
827     * Track all uids that have actively running processes.
828     */
829    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
830
831    /**
832     * This is for verifying the UID report flow.
833     */
834    static final boolean VALIDATE_UID_STATES = true;
835    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
836
837    /**
838     * Packages that the user has asked to have run in screen size
839     * compatibility mode instead of filling the screen.
840     */
841    final CompatModePackages mCompatModePackages;
842
843    /**
844     * Set of IntentSenderRecord objects that are currently active.
845     */
846    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
847            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
848
849    /**
850     * Fingerprints (hashCode()) of stack traces that we've
851     * already logged DropBox entries for.  Guarded by itself.  If
852     * something (rogue user app) forces this over
853     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
854     */
855    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
856    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
857
858    /**
859     * Strict Mode background batched logging state.
860     *
861     * The string buffer is guarded by itself, and its lock is also
862     * used to determine if another batched write is already
863     * in-flight.
864     */
865    private final StringBuilder mStrictModeBuffer = new StringBuilder();
866
867    /**
868     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
869     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
870     */
871    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
872
873    /**
874     * Resolver for broadcast intents to registered receivers.
875     * Holds BroadcastFilter (subclass of IntentFilter).
876     */
877    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
878            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
879        @Override
880        protected boolean allowFilterResult(
881                BroadcastFilter filter, List<BroadcastFilter> dest) {
882            IBinder target = filter.receiverList.receiver.asBinder();
883            for (int i = dest.size() - 1; i >= 0; i--) {
884                if (dest.get(i).receiverList.receiver.asBinder() == target) {
885                    return false;
886                }
887            }
888            return true;
889        }
890
891        @Override
892        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
893            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
894                    || userId == filter.owningUserId) {
895                return super.newResult(filter, match, userId);
896            }
897            return null;
898        }
899
900        @Override
901        protected BroadcastFilter[] newArray(int size) {
902            return new BroadcastFilter[size];
903        }
904
905        @Override
906        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
907            return packageName.equals(filter.packageName);
908        }
909    };
910
911    /**
912     * State of all active sticky broadcasts per user.  Keys are the action of the
913     * sticky Intent, values are an ArrayList of all broadcasted intents with
914     * that action (which should usually be one).  The SparseArray is keyed
915     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
916     * for stickies that are sent to all users.
917     */
918    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
919            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
920
921    final ActiveServices mServices;
922
923    final static class Association {
924        final int mSourceUid;
925        final String mSourceProcess;
926        final int mTargetUid;
927        final ComponentName mTargetComponent;
928        final String mTargetProcess;
929
930        int mCount;
931        long mTime;
932
933        int mNesting;
934        long mStartTime;
935
936        // states of the source process when the bind occurred.
937        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
938        long mLastStateUptime;
939        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
940                - ActivityManager.MIN_PROCESS_STATE+1];
941
942        Association(int sourceUid, String sourceProcess, int targetUid,
943                ComponentName targetComponent, String targetProcess) {
944            mSourceUid = sourceUid;
945            mSourceProcess = sourceProcess;
946            mTargetUid = targetUid;
947            mTargetComponent = targetComponent;
948            mTargetProcess = targetProcess;
949        }
950    }
951
952    /**
953     * When service association tracking is enabled, this is all of the associations we
954     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
955     * -> association data.
956     */
957    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
958            mAssociations = new SparseArray<>();
959    boolean mTrackingAssociations;
960
961    /**
962     * Backup/restore process management
963     */
964    String mBackupAppName = null;
965    BackupRecord mBackupTarget = null;
966
967    final ProviderMap mProviderMap;
968
969    /**
970     * List of content providers who have clients waiting for them.  The
971     * application is currently being launched and the provider will be
972     * removed from this list once it is published.
973     */
974    final ArrayList<ContentProviderRecord> mLaunchingProviders
975            = new ArrayList<ContentProviderRecord>();
976
977    /**
978     * File storing persisted {@link #mGrantedUriPermissions}.
979     */
980    private final AtomicFile mGrantFile;
981
982    /** XML constants used in {@link #mGrantFile} */
983    private static final String TAG_URI_GRANTS = "uri-grants";
984    private static final String TAG_URI_GRANT = "uri-grant";
985    private static final String ATTR_USER_HANDLE = "userHandle";
986    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
987    private static final String ATTR_TARGET_USER_ID = "targetUserId";
988    private static final String ATTR_SOURCE_PKG = "sourcePkg";
989    private static final String ATTR_TARGET_PKG = "targetPkg";
990    private static final String ATTR_URI = "uri";
991    private static final String ATTR_MODE_FLAGS = "modeFlags";
992    private static final String ATTR_CREATED_TIME = "createdTime";
993    private static final String ATTR_PREFIX = "prefix";
994
995    /**
996     * Global set of specific {@link Uri} permissions that have been granted.
997     * This optimized lookup structure maps from {@link UriPermission#targetUid}
998     * to {@link UriPermission#uri} to {@link UriPermission}.
999     */
1000    @GuardedBy("this")
1001    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1002            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1003
1004    public static class GrantUri {
1005        public final int sourceUserId;
1006        public final Uri uri;
1007        public boolean prefix;
1008
1009        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1010            this.sourceUserId = sourceUserId;
1011            this.uri = uri;
1012            this.prefix = prefix;
1013        }
1014
1015        @Override
1016        public int hashCode() {
1017            int hashCode = 1;
1018            hashCode = 31 * hashCode + sourceUserId;
1019            hashCode = 31 * hashCode + uri.hashCode();
1020            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1021            return hashCode;
1022        }
1023
1024        @Override
1025        public boolean equals(Object o) {
1026            if (o instanceof GrantUri) {
1027                GrantUri other = (GrantUri) o;
1028                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1029                        && prefix == other.prefix;
1030            }
1031            return false;
1032        }
1033
1034        @Override
1035        public String toString() {
1036            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1037            if (prefix) result += " [prefix]";
1038            return result;
1039        }
1040
1041        public String toSafeString() {
1042            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1043            if (prefix) result += " [prefix]";
1044            return result;
1045        }
1046
1047        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1048            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1049                    ContentProvider.getUriWithoutUserId(uri), false);
1050        }
1051    }
1052
1053    CoreSettingsObserver mCoreSettingsObserver;
1054
1055    FontScaleSettingObserver mFontScaleSettingObserver;
1056
1057    private final class FontScaleSettingObserver extends ContentObserver {
1058        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1059
1060        public FontScaleSettingObserver() {
1061            super(mHandler);
1062            ContentResolver resolver = mContext.getContentResolver();
1063            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1064        }
1065
1066        @Override
1067        public void onChange(boolean selfChange, Uri uri) {
1068            if (mFontScaleUri.equals(uri)) {
1069                updateFontScaleIfNeeded();
1070            }
1071        }
1072    }
1073
1074    /**
1075     * Thread-local storage used to carry caller permissions over through
1076     * indirect content-provider access.
1077     */
1078    private class Identity {
1079        public final IBinder token;
1080        public final int pid;
1081        public final int uid;
1082
1083        Identity(IBinder _token, int _pid, int _uid) {
1084            token = _token;
1085            pid = _pid;
1086            uid = _uid;
1087        }
1088    }
1089
1090    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1091
1092    /**
1093     * All information we have collected about the runtime performance of
1094     * any user id that can impact battery performance.
1095     */
1096    final BatteryStatsService mBatteryStatsService;
1097
1098    /**
1099     * Information about component usage
1100     */
1101    UsageStatsManagerInternal mUsageStatsService;
1102
1103    /**
1104     * Access to DeviceIdleController service.
1105     */
1106    DeviceIdleController.LocalService mLocalDeviceIdleController;
1107
1108    /**
1109     * Information about and control over application operations
1110     */
1111    final AppOpsService mAppOpsService;
1112
1113    /**
1114     * Current configuration information.  HistoryRecord objects are given
1115     * a reference to this object to indicate which configuration they are
1116     * currently running in, so this object must be kept immutable.
1117     */
1118    Configuration mConfiguration = new Configuration();
1119
1120    /**
1121     * Current sequencing integer of the configuration, for skipping old
1122     * configurations.
1123     */
1124    int mConfigurationSeq = 0;
1125
1126    boolean mSuppressResizeConfigChanges = false;
1127
1128    /**
1129     * Hardware-reported OpenGLES version.
1130     */
1131    final int GL_ES_VERSION;
1132
1133    /**
1134     * List of initialization arguments to pass to all processes when binding applications to them.
1135     * For example, references to the commonly used services.
1136     */
1137    HashMap<String, IBinder> mAppBindArgs;
1138
1139    /**
1140     * Temporary to avoid allocations.  Protected by main lock.
1141     */
1142    final StringBuilder mStringBuilder = new StringBuilder(256);
1143
1144    /**
1145     * Used to control how we initialize the service.
1146     */
1147    ComponentName mTopComponent;
1148    String mTopAction = Intent.ACTION_MAIN;
1149    String mTopData;
1150
1151    volatile boolean mProcessesReady = false;
1152    volatile boolean mSystemReady = false;
1153    volatile boolean mOnBattery = false;
1154    volatile int mFactoryTest;
1155
1156    @GuardedBy("this") boolean mBooting = false;
1157    @GuardedBy("this") boolean mCallFinishBooting = false;
1158    @GuardedBy("this") boolean mBootAnimationComplete = false;
1159    @GuardedBy("this") boolean mLaunchWarningShown = false;
1160    @GuardedBy("this") boolean mCheckedForSetup = false;
1161
1162    Context mContext;
1163
1164    /**
1165     * The time at which we will allow normal application switches again,
1166     * after a call to {@link #stopAppSwitches()}.
1167     */
1168    long mAppSwitchesAllowedTime;
1169
1170    /**
1171     * This is set to true after the first switch after mAppSwitchesAllowedTime
1172     * is set; any switches after that will clear the time.
1173     */
1174    boolean mDidAppSwitch;
1175
1176    /**
1177     * Last time (in realtime) at which we checked for power usage.
1178     */
1179    long mLastPowerCheckRealtime;
1180
1181    /**
1182     * Last time (in uptime) at which we checked for power usage.
1183     */
1184    long mLastPowerCheckUptime;
1185
1186    /**
1187     * Set while we are wanting to sleep, to prevent any
1188     * activities from being started/resumed.
1189     */
1190    private boolean mSleeping = false;
1191
1192    /**
1193     * The process state used for processes that are running the top activities.
1194     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1195     */
1196    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1197
1198    /**
1199     * Set while we are running a voice interaction.  This overrides
1200     * sleeping while it is active.
1201     */
1202    private IVoiceInteractionSession mRunningVoice;
1203
1204    /**
1205     * For some direct access we need to power manager.
1206     */
1207    PowerManagerInternal mLocalPowerManager;
1208
1209    /**
1210     * We want to hold a wake lock while running a voice interaction session, since
1211     * this may happen with the screen off and we need to keep the CPU running to
1212     * be able to continue to interact with the user.
1213     */
1214    PowerManager.WakeLock mVoiceWakeLock;
1215
1216    /**
1217     * State of external calls telling us if the device is awake or asleep.
1218     */
1219    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1220
1221    /**
1222     * A list of tokens that cause the top activity to be put to sleep.
1223     * They are used by components that may hide and block interaction with underlying
1224     * activities.
1225     */
1226    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1227
1228    static final int LOCK_SCREEN_HIDDEN = 0;
1229    static final int LOCK_SCREEN_LEAVING = 1;
1230    static final int LOCK_SCREEN_SHOWN = 2;
1231    /**
1232     * State of external call telling us if the lock screen is shown.
1233     */
1234    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1235
1236    /**
1237     * Set if we are shutting down the system, similar to sleeping.
1238     */
1239    boolean mShuttingDown = false;
1240
1241    /**
1242     * Current sequence id for oom_adj computation traversal.
1243     */
1244    int mAdjSeq = 0;
1245
1246    /**
1247     * Current sequence id for process LRU updating.
1248     */
1249    int mLruSeq = 0;
1250
1251    /**
1252     * Keep track of the non-cached/empty process we last found, to help
1253     * determine how to distribute cached/empty processes next time.
1254     */
1255    int mNumNonCachedProcs = 0;
1256
1257    /**
1258     * Keep track of the number of cached hidden procs, to balance oom adj
1259     * distribution between those and empty procs.
1260     */
1261    int mNumCachedHiddenProcs = 0;
1262
1263    /**
1264     * Keep track of the number of service processes we last found, to
1265     * determine on the next iteration which should be B services.
1266     */
1267    int mNumServiceProcs = 0;
1268    int mNewNumAServiceProcs = 0;
1269    int mNewNumServiceProcs = 0;
1270
1271    /**
1272     * Allow the current computed overall memory level of the system to go down?
1273     * This is set to false when we are killing processes for reasons other than
1274     * memory management, so that the now smaller process list will not be taken as
1275     * an indication that memory is tighter.
1276     */
1277    boolean mAllowLowerMemLevel = false;
1278
1279    /**
1280     * The last computed memory level, for holding when we are in a state that
1281     * processes are going away for other reasons.
1282     */
1283    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1284
1285    /**
1286     * The last total number of process we have, to determine if changes actually look
1287     * like a shrinking number of process due to lower RAM.
1288     */
1289    int mLastNumProcesses;
1290
1291    /**
1292     * The uptime of the last time we performed idle maintenance.
1293     */
1294    long mLastIdleTime = SystemClock.uptimeMillis();
1295
1296    /**
1297     * Total time spent with RAM that has been added in the past since the last idle time.
1298     */
1299    long mLowRamTimeSinceLastIdle = 0;
1300
1301    /**
1302     * If RAM is currently low, when that horrible situation started.
1303     */
1304    long mLowRamStartTime = 0;
1305
1306    /**
1307     * For reporting to battery stats the current top application.
1308     */
1309    private String mCurResumedPackage = null;
1310    private int mCurResumedUid = -1;
1311
1312    /**
1313     * For reporting to battery stats the apps currently running foreground
1314     * service.  The ProcessMap is package/uid tuples; each of these contain
1315     * an array of the currently foreground processes.
1316     */
1317    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1318            = new ProcessMap<ArrayList<ProcessRecord>>();
1319
1320    /**
1321     * This is set if we had to do a delayed dexopt of an app before launching
1322     * it, to increase the ANR timeouts in that case.
1323     */
1324    boolean mDidDexOpt;
1325
1326    /**
1327     * Set if the systemServer made a call to enterSafeMode.
1328     */
1329    boolean mSafeMode;
1330
1331    /**
1332     * If true, we are running under a test environment so will sample PSS from processes
1333     * much more rapidly to try to collect better data when the tests are rapidly
1334     * running through apps.
1335     */
1336    boolean mTestPssMode = false;
1337
1338    String mDebugApp = null;
1339    boolean mWaitForDebugger = false;
1340    boolean mDebugTransient = false;
1341    String mOrigDebugApp = null;
1342    boolean mOrigWaitForDebugger = false;
1343    boolean mAlwaysFinishActivities = false;
1344    boolean mLenientBackgroundCheck = false;
1345    boolean mForceResizableActivities;
1346    boolean mSupportsMultiWindow;
1347    boolean mSupportsFreeformWindowManagement;
1348    boolean mSupportsPictureInPicture;
1349    boolean mSupportsLeanbackOnly;
1350    Rect mDefaultPinnedStackBounds;
1351    IActivityController mController = null;
1352    boolean mControllerIsAMonkey = false;
1353    String mProfileApp = null;
1354    ProcessRecord mProfileProc = null;
1355    String mProfileFile;
1356    ParcelFileDescriptor mProfileFd;
1357    int mSamplingInterval = 0;
1358    boolean mAutoStopProfiler = false;
1359    int mProfileType = 0;
1360    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1361    String mMemWatchDumpProcName;
1362    String mMemWatchDumpFile;
1363    int mMemWatchDumpPid;
1364    int mMemWatchDumpUid;
1365    String mTrackAllocationApp = null;
1366    String mNativeDebuggingApp = null;
1367
1368    final long[] mTmpLong = new long[2];
1369
1370    static final class ProcessChangeItem {
1371        static final int CHANGE_ACTIVITIES = 1<<0;
1372        static final int CHANGE_PROCESS_STATE = 1<<1;
1373        int changes;
1374        int uid;
1375        int pid;
1376        int processState;
1377        boolean foregroundActivities;
1378    }
1379
1380    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1381    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1382
1383    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1384    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1385
1386    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1387    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1388
1389    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1390    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1391
1392    /**
1393     * Runtime CPU use collection thread.  This object's lock is used to
1394     * perform synchronization with the thread (notifying it to run).
1395     */
1396    final Thread mProcessCpuThread;
1397
1398    /**
1399     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1400     * Must acquire this object's lock when accessing it.
1401     * NOTE: this lock will be held while doing long operations (trawling
1402     * through all processes in /proc), so it should never be acquired by
1403     * any critical paths such as when holding the main activity manager lock.
1404     */
1405    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1406            MONITOR_THREAD_CPU_USAGE);
1407    final AtomicLong mLastCpuTime = new AtomicLong(0);
1408    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1409
1410    long mLastWriteTime = 0;
1411
1412    /**
1413     * Used to retain an update lock when the foreground activity is in
1414     * immersive mode.
1415     */
1416    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1417
1418    /**
1419     * Set to true after the system has finished booting.
1420     */
1421    boolean mBooted = false;
1422
1423    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1424    int mProcessLimitOverride = -1;
1425
1426    WindowManagerService mWindowManager;
1427    final ActivityThread mSystemThread;
1428
1429    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1430        final ProcessRecord mApp;
1431        final int mPid;
1432        final IApplicationThread mAppThread;
1433
1434        AppDeathRecipient(ProcessRecord app, int pid,
1435                IApplicationThread thread) {
1436            if (DEBUG_ALL) Slog.v(
1437                TAG, "New death recipient " + this
1438                + " for thread " + thread.asBinder());
1439            mApp = app;
1440            mPid = pid;
1441            mAppThread = thread;
1442        }
1443
1444        @Override
1445        public void binderDied() {
1446            if (DEBUG_ALL) Slog.v(
1447                TAG, "Death received in " + this
1448                + " for thread " + mAppThread.asBinder());
1449            synchronized(ActivityManagerService.this) {
1450                appDiedLocked(mApp, mPid, mAppThread, true);
1451            }
1452        }
1453    }
1454
1455    static final int SHOW_ERROR_UI_MSG = 1;
1456    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1457    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1458    static final int UPDATE_CONFIGURATION_MSG = 4;
1459    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1460    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1461    static final int SERVICE_TIMEOUT_MSG = 12;
1462    static final int UPDATE_TIME_ZONE = 13;
1463    static final int SHOW_UID_ERROR_UI_MSG = 14;
1464    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1465    static final int PROC_START_TIMEOUT_MSG = 20;
1466    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1467    static final int KILL_APPLICATION_MSG = 22;
1468    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1469    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1470    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1471    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1472    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1473    static final int CLEAR_DNS_CACHE_MSG = 28;
1474    static final int UPDATE_HTTP_PROXY_MSG = 29;
1475    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1476    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1477    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1478    static final int REPORT_MEM_USAGE_MSG = 33;
1479    static final int REPORT_USER_SWITCH_MSG = 34;
1480    static final int CONTINUE_USER_SWITCH_MSG = 35;
1481    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1482    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1483    static final int PERSIST_URI_GRANTS_MSG = 38;
1484    static final int REQUEST_ALL_PSS_MSG = 39;
1485    static final int START_PROFILES_MSG = 40;
1486    static final int UPDATE_TIME = 41;
1487    static final int SYSTEM_USER_START_MSG = 42;
1488    static final int SYSTEM_USER_CURRENT_MSG = 43;
1489    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1490    static final int FINISH_BOOTING_MSG = 45;
1491    static final int START_USER_SWITCH_UI_MSG = 46;
1492    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1493    static final int DISMISS_DIALOG_UI_MSG = 48;
1494    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1495    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1496    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1497    static final int DELETE_DUMPHEAP_MSG = 52;
1498    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1499    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1500    static final int REPORT_TIME_TRACKER_MSG = 55;
1501    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1502    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1503    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1504    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1505    static final int IDLE_UIDS_MSG = 60;
1506    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1507    static final int LOG_STACK_STATE = 62;
1508    static final int VR_MODE_CHANGE_MSG = 63;
1509    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1510    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1511    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1512    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1513    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1514    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1515
1516    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1517    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1518    static final int FIRST_COMPAT_MODE_MSG = 300;
1519    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1520
1521    static ServiceThread sKillThread = null;
1522    static KillHandler sKillHandler = null;
1523
1524    CompatModeDialog mCompatModeDialog;
1525    long mLastMemUsageReportTime = 0;
1526
1527    /**
1528     * Flag whether the current user is a "monkey", i.e. whether
1529     * the UI is driven by a UI automation tool.
1530     */
1531    private boolean mUserIsMonkey;
1532
1533    /** Flag whether the device has a Recents UI */
1534    boolean mHasRecents;
1535
1536    /** The dimensions of the thumbnails in the Recents UI. */
1537    int mThumbnailWidth;
1538    int mThumbnailHeight;
1539    float mFullscreenThumbnailScale;
1540
1541    final ServiceThread mHandlerThread;
1542    final MainHandler mHandler;
1543    final UiHandler mUiHandler;
1544
1545    PackageManagerInternal mPackageManagerInt;
1546
1547    // VoiceInteraction session ID that changes for each new request except when
1548    // being called for multiwindow assist in a single session.
1549    private int mViSessionId = 1000;
1550
1551    final class KillHandler extends Handler {
1552        static final int KILL_PROCESS_GROUP_MSG = 4000;
1553
1554        public KillHandler(Looper looper) {
1555            super(looper, null, true);
1556        }
1557
1558        @Override
1559        public void handleMessage(Message msg) {
1560            switch (msg.what) {
1561                case KILL_PROCESS_GROUP_MSG:
1562                {
1563                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1564                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1565                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1566                }
1567                break;
1568
1569                default:
1570                    super.handleMessage(msg);
1571            }
1572        }
1573    }
1574
1575    final class UiHandler extends Handler {
1576        public UiHandler() {
1577            super(com.android.server.UiThread.get().getLooper(), null, true);
1578        }
1579
1580        @Override
1581        public void handleMessage(Message msg) {
1582            switch (msg.what) {
1583            case SHOW_ERROR_UI_MSG: {
1584                mAppErrors.handleShowAppErrorUi(msg);
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_NOT_RESPONDING_UI_MSG: {
1588                mAppErrors.handleShowAnrUi(msg);
1589                ensureBootCompleted();
1590            } break;
1591            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1592                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1593                synchronized (ActivityManagerService.this) {
1594                    ProcessRecord proc = (ProcessRecord) data.get("app");
1595                    if (proc == null) {
1596                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1597                        break;
1598                    }
1599                    if (proc.crashDialog != null) {
1600                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1601                        return;
1602                    }
1603                    AppErrorResult res = (AppErrorResult) data.get("result");
1604                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1605                        Dialog d = new StrictModeViolationDialog(mContext,
1606                                ActivityManagerService.this, res, proc);
1607                        d.show();
1608                        proc.crashDialog = d;
1609                    } else {
1610                        // The device is asleep, so just pretend that the user
1611                        // saw a crash dialog and hit "force quit".
1612                        res.set(0);
1613                    }
1614                }
1615                ensureBootCompleted();
1616            } break;
1617            case SHOW_FACTORY_ERROR_UI_MSG: {
1618                Dialog d = new FactoryErrorDialog(
1619                    mContext, msg.getData().getCharSequence("msg"));
1620                d.show();
1621                ensureBootCompleted();
1622            } break;
1623            case WAIT_FOR_DEBUGGER_UI_MSG: {
1624                synchronized (ActivityManagerService.this) {
1625                    ProcessRecord app = (ProcessRecord)msg.obj;
1626                    if (msg.arg1 != 0) {
1627                        if (!app.waitedForDebugger) {
1628                            Dialog d = new AppWaitingForDebuggerDialog(
1629                                    ActivityManagerService.this,
1630                                    mContext, app);
1631                            app.waitDialog = d;
1632                            app.waitedForDebugger = true;
1633                            d.show();
1634                        }
1635                    } else {
1636                        if (app.waitDialog != null) {
1637                            app.waitDialog.dismiss();
1638                            app.waitDialog = null;
1639                        }
1640                    }
1641                }
1642            } break;
1643            case SHOW_UID_ERROR_UI_MSG: {
1644                if (mShowDialogs) {
1645                    AlertDialog d = new BaseErrorDialog(mContext);
1646                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1647                    d.setCancelable(false);
1648                    d.setTitle(mContext.getText(R.string.android_system_label));
1649                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1650                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1651                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1652                    d.show();
1653                }
1654            } break;
1655            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1656                if (mShowDialogs) {
1657                    AlertDialog d = new BaseErrorDialog(mContext);
1658                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659                    d.setCancelable(false);
1660                    d.setTitle(mContext.getText(R.string.android_system_label));
1661                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1662                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1664                    d.show();
1665                }
1666            } break;
1667            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1668                synchronized (ActivityManagerService.this) {
1669                    ActivityRecord ar = (ActivityRecord) msg.obj;
1670                    if (mCompatModeDialog != null) {
1671                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1672                                ar.info.applicationInfo.packageName)) {
1673                            return;
1674                        }
1675                        mCompatModeDialog.dismiss();
1676                        mCompatModeDialog = null;
1677                    }
1678                    if (ar != null && false) {
1679                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1680                                ar.packageName)) {
1681                            int mode = mCompatModePackages.computeCompatModeLocked(
1682                                    ar.info.applicationInfo);
1683                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1684                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1685                                mCompatModeDialog = new CompatModeDialog(
1686                                        ActivityManagerService.this, mContext,
1687                                        ar.info.applicationInfo);
1688                                mCompatModeDialog.show();
1689                            }
1690                        }
1691                    }
1692                }
1693                break;
1694            }
1695            case START_USER_SWITCH_UI_MSG: {
1696                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1697                break;
1698            }
1699            case DISMISS_DIALOG_UI_MSG: {
1700                final Dialog d = (Dialog) msg.obj;
1701                d.dismiss();
1702                break;
1703            }
1704            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1705                dispatchProcessesChanged();
1706                break;
1707            }
1708            case DISPATCH_PROCESS_DIED_UI_MSG: {
1709                final int pid = msg.arg1;
1710                final int uid = msg.arg2;
1711                dispatchProcessDied(pid, uid);
1712                break;
1713            }
1714            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1715                dispatchUidsChanged();
1716            } break;
1717            }
1718        }
1719    }
1720
1721    final class MainHandler extends Handler {
1722        public MainHandler(Looper looper) {
1723            super(looper, null, true);
1724        }
1725
1726        @Override
1727        public void handleMessage(Message msg) {
1728            switch (msg.what) {
1729            case UPDATE_CONFIGURATION_MSG: {
1730                final ContentResolver resolver = mContext.getContentResolver();
1731                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1732                        msg.arg1);
1733            } break;
1734            case GC_BACKGROUND_PROCESSES_MSG: {
1735                synchronized (ActivityManagerService.this) {
1736                    performAppGcsIfAppropriateLocked();
1737                }
1738            } break;
1739            case SERVICE_TIMEOUT_MSG: {
1740                if (mDidDexOpt) {
1741                    mDidDexOpt = false;
1742                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1743                    nmsg.obj = msg.obj;
1744                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1745                    return;
1746                }
1747                mServices.serviceTimeout((ProcessRecord)msg.obj);
1748            } break;
1749            case UPDATE_TIME_ZONE: {
1750                synchronized (ActivityManagerService.this) {
1751                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1752                        ProcessRecord r = mLruProcesses.get(i);
1753                        if (r.thread != null) {
1754                            try {
1755                                r.thread.updateTimeZone();
1756                            } catch (RemoteException ex) {
1757                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1758                            }
1759                        }
1760                    }
1761                }
1762            } break;
1763            case CLEAR_DNS_CACHE_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1766                        ProcessRecord r = mLruProcesses.get(i);
1767                        if (r.thread != null) {
1768                            try {
1769                                r.thread.clearDnsCache();
1770                            } catch (RemoteException ex) {
1771                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1772                            }
1773                        }
1774                    }
1775                }
1776            } break;
1777            case UPDATE_HTTP_PROXY_MSG: {
1778                ProxyInfo proxy = (ProxyInfo)msg.obj;
1779                String host = "";
1780                String port = "";
1781                String exclList = "";
1782                Uri pacFileUrl = Uri.EMPTY;
1783                if (proxy != null) {
1784                    host = proxy.getHost();
1785                    port = Integer.toString(proxy.getPort());
1786                    exclList = proxy.getExclusionListAsString();
1787                    pacFileUrl = proxy.getPacFileUrl();
1788                }
1789                synchronized (ActivityManagerService.this) {
1790                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1791                        ProcessRecord r = mLruProcesses.get(i);
1792                        if (r.thread != null) {
1793                            try {
1794                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1795                            } catch (RemoteException ex) {
1796                                Slog.w(TAG, "Failed to update http proxy for: " +
1797                                        r.info.processName);
1798                            }
1799                        }
1800                    }
1801                }
1802            } break;
1803            case PROC_START_TIMEOUT_MSG: {
1804                if (mDidDexOpt) {
1805                    mDidDexOpt = false;
1806                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1807                    nmsg.obj = msg.obj;
1808                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1809                    return;
1810                }
1811                ProcessRecord app = (ProcessRecord)msg.obj;
1812                synchronized (ActivityManagerService.this) {
1813                    processStartTimedOutLocked(app);
1814                }
1815            } break;
1816            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1817                ProcessRecord app = (ProcessRecord)msg.obj;
1818                synchronized (ActivityManagerService.this) {
1819                    processContentProviderPublishTimedOutLocked(app);
1820                }
1821            } break;
1822            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1825                }
1826            } break;
1827            case KILL_APPLICATION_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    int appid = msg.arg1;
1830                    boolean restart = (msg.arg2 == 1);
1831                    Bundle bundle = (Bundle)msg.obj;
1832                    String pkg = bundle.getString("pkg");
1833                    String reason = bundle.getString("reason");
1834                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1835                            false, UserHandle.USER_ALL, reason);
1836                }
1837            } break;
1838            case FINALIZE_PENDING_INTENT_MSG: {
1839                ((PendingIntentRecord)msg.obj).completeFinalize();
1840            } break;
1841            case POST_HEAVY_NOTIFICATION_MSG: {
1842                INotificationManager inm = NotificationManager.getService();
1843                if (inm == null) {
1844                    return;
1845                }
1846
1847                ActivityRecord root = (ActivityRecord)msg.obj;
1848                ProcessRecord process = root.app;
1849                if (process == null) {
1850                    return;
1851                }
1852
1853                try {
1854                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1855                    String text = mContext.getString(R.string.heavy_weight_notification,
1856                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1857                    Notification notification = new Notification.Builder(context)
1858                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1859                            .setWhen(0)
1860                            .setOngoing(true)
1861                            .setTicker(text)
1862                            .setColor(mContext.getColor(
1863                                    com.android.internal.R.color.system_notification_accent_color))
1864                            .setContentTitle(text)
1865                            .setContentText(
1866                                    mContext.getText(R.string.heavy_weight_notification_detail))
1867                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1868                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1869                                    new UserHandle(root.userId)))
1870                            .build();
1871                    try {
1872                        int[] outId = new int[1];
1873                        inm.enqueueNotificationWithTag("android", "android", null,
1874                                R.string.heavy_weight_notification,
1875                                notification, outId, root.userId);
1876                    } catch (RuntimeException e) {
1877                        Slog.w(ActivityManagerService.TAG,
1878                                "Error showing notification for heavy-weight app", e);
1879                    } catch (RemoteException e) {
1880                    }
1881                } catch (NameNotFoundException e) {
1882                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1883                }
1884            } break;
1885            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1886                INotificationManager inm = NotificationManager.getService();
1887                if (inm == null) {
1888                    return;
1889                }
1890                try {
1891                    inm.cancelNotificationWithTag("android", null,
1892                            R.string.heavy_weight_notification,  msg.arg1);
1893                } catch (RuntimeException e) {
1894                    Slog.w(ActivityManagerService.TAG,
1895                            "Error canceling notification for service", e);
1896                } catch (RemoteException e) {
1897                }
1898            } break;
1899            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1900                synchronized (ActivityManagerService.this) {
1901                    checkExcessivePowerUsageLocked(true);
1902                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1903                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1905                }
1906            } break;
1907            case REPORT_MEM_USAGE_MSG: {
1908                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1909                Thread thread = new Thread() {
1910                    @Override public void run() {
1911                        reportMemUsage(memInfos);
1912                    }
1913                };
1914                thread.start();
1915                break;
1916            }
1917            case REPORT_USER_SWITCH_MSG: {
1918                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1919                break;
1920            }
1921            case CONTINUE_USER_SWITCH_MSG: {
1922                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1923                break;
1924            }
1925            case USER_SWITCH_TIMEOUT_MSG: {
1926                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1927                break;
1928            }
1929            case IMMERSIVE_MODE_LOCK_MSG: {
1930                final boolean nextState = (msg.arg1 != 0);
1931                if (mUpdateLock.isHeld() != nextState) {
1932                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1933                            "Applying new update lock state '" + nextState
1934                            + "' for " + (ActivityRecord)msg.obj);
1935                    if (nextState) {
1936                        mUpdateLock.acquire();
1937                    } else {
1938                        mUpdateLock.release();
1939                    }
1940                }
1941                break;
1942            }
1943            case PERSIST_URI_GRANTS_MSG: {
1944                writeGrantedUriPermissions();
1945                break;
1946            }
1947            case REQUEST_ALL_PSS_MSG: {
1948                synchronized (ActivityManagerService.this) {
1949                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1950                }
1951                break;
1952            }
1953            case START_PROFILES_MSG: {
1954                synchronized (ActivityManagerService.this) {
1955                    mUserController.startProfilesLocked();
1956                }
1957                break;
1958            }
1959            case UPDATE_TIME: {
1960                synchronized (ActivityManagerService.this) {
1961                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1962                        ProcessRecord r = mLruProcesses.get(i);
1963                        if (r.thread != null) {
1964                            try {
1965                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1966                            } catch (RemoteException ex) {
1967                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1968                            }
1969                        }
1970                    }
1971                }
1972                break;
1973            }
1974            case SYSTEM_USER_START_MSG: {
1975                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1976                        Integer.toString(msg.arg1), msg.arg1);
1977                mSystemServiceManager.startUser(msg.arg1);
1978                break;
1979            }
1980            case SYSTEM_USER_UNLOCK_MSG: {
1981                final int userId = msg.arg1;
1982                mSystemServiceManager.unlockUser(userId);
1983                synchronized (ActivityManagerService.this) {
1984                    mRecentTasks.loadUserRecentsLocked(userId);
1985                }
1986                if (userId == UserHandle.USER_SYSTEM) {
1987                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1988                }
1989                installEncryptionUnawareProviders(userId);
1990                mUserController.finishUserUnlocked((UserState) msg.obj);
1991                break;
1992            }
1993            case SYSTEM_USER_CURRENT_MSG: {
1994                mBatteryStatsService.noteEvent(
1995                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1996                        Integer.toString(msg.arg2), msg.arg2);
1997                mBatteryStatsService.noteEvent(
1998                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1999                        Integer.toString(msg.arg1), msg.arg1);
2000                mSystemServiceManager.switchUser(msg.arg1);
2001                break;
2002            }
2003            case ENTER_ANIMATION_COMPLETE_MSG: {
2004                synchronized (ActivityManagerService.this) {
2005                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2006                    if (r != null && r.app != null && r.app.thread != null) {
2007                        try {
2008                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2009                        } catch (RemoteException e) {
2010                        }
2011                    }
2012                }
2013                break;
2014            }
2015            case FINISH_BOOTING_MSG: {
2016                if (msg.arg1 != 0) {
2017                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2018                    finishBooting();
2019                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2020                }
2021                if (msg.arg2 != 0) {
2022                    enableScreenAfterBoot();
2023                }
2024                break;
2025            }
2026            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2027                try {
2028                    Locale l = (Locale) msg.obj;
2029                    IBinder service = ServiceManager.getService("mount");
2030                    IMountService mountService = IMountService.Stub.asInterface(service);
2031                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2032                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2033                } catch (RemoteException e) {
2034                    Log.e(TAG, "Error storing locale for decryption UI", e);
2035                }
2036                break;
2037            }
2038            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2039                synchronized (ActivityManagerService.this) {
2040                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2041                        try {
2042                            // Make a one-way callback to the listener
2043                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2044                        } catch (RemoteException e){
2045                            // Handled by the RemoteCallbackList
2046                        }
2047                    }
2048                    mTaskStackListeners.finishBroadcast();
2049                }
2050                break;
2051            }
2052            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2053                synchronized (ActivityManagerService.this) {
2054                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2055                        try {
2056                            // Make a one-way callback to the listener
2057                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2058                        } catch (RemoteException e){
2059                            // Handled by the RemoteCallbackList
2060                        }
2061                    }
2062                    mTaskStackListeners.finishBroadcast();
2063                }
2064                break;
2065            }
2066            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2067                synchronized (ActivityManagerService.this) {
2068                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2069                        try {
2070                            // Make a one-way callback to the listener
2071                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2072                        } catch (RemoteException e){
2073                            // Handled by the RemoteCallbackList
2074                        }
2075                    }
2076                    mTaskStackListeners.finishBroadcast();
2077                }
2078                break;
2079            }
2080            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2081                synchronized (ActivityManagerService.this) {
2082                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2083                        try {
2084                            // Make a one-way callback to the listener
2085                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2086                        } catch (RemoteException e){
2087                            // Handled by the RemoteCallbackList
2088                        }
2089                    }
2090                    mTaskStackListeners.finishBroadcast();
2091                }
2092                break;
2093            }
2094            case NOTIFY_FORCED_RESIZABLE_MSG: {
2095                synchronized (ActivityManagerService.this) {
2096                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097                        try {
2098                            // Make a one-way callback to the listener
2099                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2100                                    (String) msg.obj, msg.arg1);
2101                        } catch (RemoteException e){
2102                            // Handled by the RemoteCallbackList
2103                        }
2104                    }
2105                    mTaskStackListeners.finishBroadcast();
2106                }
2107                break;
2108            }
2109                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2110                    synchronized (ActivityManagerService.this) {
2111                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2112                            try {
2113                                // Make a one-way callback to the listener
2114                                mTaskStackListeners.getBroadcastItem(i)
2115                                        .onActivityDismissingDockedStack();
2116                            } catch (RemoteException e){
2117                                // Handled by the RemoteCallbackList
2118                            }
2119                        }
2120                        mTaskStackListeners.finishBroadcast();
2121                    }
2122                    break;
2123                }
2124            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2125                final int uid = msg.arg1;
2126                final byte[] firstPacket = (byte[]) msg.obj;
2127
2128                synchronized (mPidsSelfLocked) {
2129                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2130                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2131                        if (p.uid == uid) {
2132                            try {
2133                                p.thread.notifyCleartextNetwork(firstPacket);
2134                            } catch (RemoteException ignored) {
2135                            }
2136                        }
2137                    }
2138                }
2139                break;
2140            }
2141            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2142                final String procName;
2143                final int uid;
2144                final long memLimit;
2145                final String reportPackage;
2146                synchronized (ActivityManagerService.this) {
2147                    procName = mMemWatchDumpProcName;
2148                    uid = mMemWatchDumpUid;
2149                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2150                    if (val == null) {
2151                        val = mMemWatchProcesses.get(procName, 0);
2152                    }
2153                    if (val != null) {
2154                        memLimit = val.first;
2155                        reportPackage = val.second;
2156                    } else {
2157                        memLimit = 0;
2158                        reportPackage = null;
2159                    }
2160                }
2161                if (procName == null) {
2162                    return;
2163                }
2164
2165                if (DEBUG_PSS) Slog.d(TAG_PSS,
2166                        "Showing dump heap notification from " + procName + "/" + uid);
2167
2168                INotificationManager inm = NotificationManager.getService();
2169                if (inm == null) {
2170                    return;
2171                }
2172
2173                String text = mContext.getString(R.string.dump_heap_notification, procName);
2174
2175
2176                Intent deleteIntent = new Intent();
2177                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2178                Intent intent = new Intent();
2179                intent.setClassName("android", DumpHeapActivity.class.getName());
2180                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2181                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2182                if (reportPackage != null) {
2183                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2184                }
2185                int userId = UserHandle.getUserId(uid);
2186                Notification notification = new Notification.Builder(mContext)
2187                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2188                        .setWhen(0)
2189                        .setOngoing(true)
2190                        .setAutoCancel(true)
2191                        .setTicker(text)
2192                        .setColor(mContext.getColor(
2193                                com.android.internal.R.color.system_notification_accent_color))
2194                        .setContentTitle(text)
2195                        .setContentText(
2196                                mContext.getText(R.string.dump_heap_notification_detail))
2197                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2198                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2199                                new UserHandle(userId)))
2200                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2201                                deleteIntent, 0, UserHandle.SYSTEM))
2202                        .build();
2203
2204                try {
2205                    int[] outId = new int[1];
2206                    inm.enqueueNotificationWithTag("android", "android", null,
2207                            R.string.dump_heap_notification,
2208                            notification, outId, userId);
2209                } catch (RuntimeException e) {
2210                    Slog.w(ActivityManagerService.TAG,
2211                            "Error showing notification for dump heap", e);
2212                } catch (RemoteException e) {
2213                }
2214            } break;
2215            case DELETE_DUMPHEAP_MSG: {
2216                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2217                        DumpHeapActivity.JAVA_URI,
2218                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2219                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2220                        UserHandle.myUserId());
2221                synchronized (ActivityManagerService.this) {
2222                    mMemWatchDumpFile = null;
2223                    mMemWatchDumpProcName = null;
2224                    mMemWatchDumpPid = -1;
2225                    mMemWatchDumpUid = -1;
2226                }
2227            } break;
2228            case FOREGROUND_PROFILE_CHANGED_MSG: {
2229                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2230            } break;
2231            case REPORT_TIME_TRACKER_MSG: {
2232                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2233                tracker.deliverResult(mContext);
2234            } break;
2235            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2236                mUserController.dispatchUserSwitchComplete(msg.arg1);
2237            } break;
2238            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2239                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2240                try {
2241                    connection.shutdown();
2242                } catch (RemoteException e) {
2243                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2244                }
2245                // Only a UiAutomation can set this flag and now that
2246                // it is finished we make sure it is reset to its default.
2247                mUserIsMonkey = false;
2248            } break;
2249            case APP_BOOST_DEACTIVATE_MSG: {
2250                synchronized(ActivityManagerService.this) {
2251                    if (mIsBoosted) {
2252                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2253                            nativeMigrateFromBoost();
2254                            mIsBoosted = false;
2255                            mBoostStartTime = 0;
2256                        } else {
2257                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2258                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2259                        }
2260                    }
2261                }
2262            } break;
2263            case IDLE_UIDS_MSG: {
2264                idleUids();
2265            } break;
2266            case LOG_STACK_STATE: {
2267                synchronized (ActivityManagerService.this) {
2268                    mStackSupervisor.logStackState();
2269                }
2270            } break;
2271            case VR_MODE_CHANGE_MSG: {
2272                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2273                final ActivityRecord r = (ActivityRecord) msg.obj;
2274                boolean vrMode;
2275                ComponentName requestedPackage;
2276                ComponentName callingPackage;
2277                int userId;
2278                synchronized (ActivityManagerService.this) {
2279                    vrMode = r.requestedVrComponent != null;
2280                    requestedPackage = r.requestedVrComponent;
2281                    userId = r.userId;
2282                    callingPackage = r.info.getComponentName();
2283                    if (mInVrMode != vrMode) {
2284                        mInVrMode = vrMode;
2285                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2286                    }
2287                }
2288                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2289            } break;
2290            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2291                final ActivityRecord r = (ActivityRecord) msg.obj;
2292                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2293                if (needsVrMode) {
2294                    VrManagerInternal vrService =
2295                            LocalServices.getService(VrManagerInternal.class);
2296                    boolean enable = msg.arg1 == 1;
2297                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2298                            r.info.getComponentName());
2299                }
2300            } break;
2301            }
2302        }
2303    };
2304
2305    static final int COLLECT_PSS_BG_MSG = 1;
2306
2307    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2308        @Override
2309        public void handleMessage(Message msg) {
2310            switch (msg.what) {
2311            case COLLECT_PSS_BG_MSG: {
2312                long start = SystemClock.uptimeMillis();
2313                MemInfoReader memInfo = null;
2314                synchronized (ActivityManagerService.this) {
2315                    if (mFullPssPending) {
2316                        mFullPssPending = false;
2317                        memInfo = new MemInfoReader();
2318                    }
2319                }
2320                if (memInfo != null) {
2321                    updateCpuStatsNow();
2322                    long nativeTotalPss = 0;
2323                    synchronized (mProcessCpuTracker) {
2324                        final int N = mProcessCpuTracker.countStats();
2325                        for (int j=0; j<N; j++) {
2326                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2327                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2328                                // This is definitely an application process; skip it.
2329                                continue;
2330                            }
2331                            synchronized (mPidsSelfLocked) {
2332                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2333                                    // This is one of our own processes; skip it.
2334                                    continue;
2335                                }
2336                            }
2337                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2338                        }
2339                    }
2340                    memInfo.readMemInfo();
2341                    synchronized (ActivityManagerService.this) {
2342                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2343                                + (SystemClock.uptimeMillis()-start) + "ms");
2344                        final long cachedKb = memInfo.getCachedSizeKb();
2345                        final long freeKb = memInfo.getFreeSizeKb();
2346                        final long zramKb = memInfo.getZramTotalSizeKb();
2347                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2348                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2349                                kernelKb*1024, nativeTotalPss*1024);
2350                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2351                                nativeTotalPss);
2352                    }
2353                }
2354
2355                int num = 0;
2356                long[] tmp = new long[2];
2357                do {
2358                    ProcessRecord proc;
2359                    int procState;
2360                    int pid;
2361                    long lastPssTime;
2362                    synchronized (ActivityManagerService.this) {
2363                        if (mPendingPssProcesses.size() <= 0) {
2364                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2365                                    "Collected PSS of " + num + " processes in "
2366                                    + (SystemClock.uptimeMillis() - start) + "ms");
2367                            mPendingPssProcesses.clear();
2368                            return;
2369                        }
2370                        proc = mPendingPssProcesses.remove(0);
2371                        procState = proc.pssProcState;
2372                        lastPssTime = proc.lastPssTime;
2373                        if (proc.thread != null && procState == proc.setProcState
2374                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2375                                        < SystemClock.uptimeMillis()) {
2376                            pid = proc.pid;
2377                        } else {
2378                            proc = null;
2379                            pid = 0;
2380                        }
2381                    }
2382                    if (proc != null) {
2383                        long pss = Debug.getPss(pid, tmp, null);
2384                        synchronized (ActivityManagerService.this) {
2385                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2386                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2387                                num++;
2388                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2389                                        SystemClock.uptimeMillis());
2390                            }
2391                        }
2392                    }
2393                } while (true);
2394            }
2395            }
2396        }
2397    };
2398
2399    public void setSystemProcess() {
2400        try {
2401            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2402            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2403            ServiceManager.addService("meminfo", new MemBinder(this));
2404            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2405            ServiceManager.addService("dbinfo", new DbBinder(this));
2406            if (MONITOR_CPU_USAGE) {
2407                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2408            }
2409            ServiceManager.addService("permission", new PermissionController(this));
2410            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2411
2412            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2413                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2414            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2415
2416            synchronized (this) {
2417                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2418                app.persistent = true;
2419                app.pid = MY_PID;
2420                app.maxAdj = ProcessList.SYSTEM_ADJ;
2421                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2422                synchronized (mPidsSelfLocked) {
2423                    mPidsSelfLocked.put(app.pid, app);
2424                }
2425                updateLruProcessLocked(app, false, null);
2426                updateOomAdjLocked();
2427            }
2428        } catch (PackageManager.NameNotFoundException e) {
2429            throw new RuntimeException(
2430                    "Unable to find android system package", e);
2431        }
2432    }
2433
2434    public void setWindowManager(WindowManagerService wm) {
2435        mWindowManager = wm;
2436        mStackSupervisor.setWindowManager(wm);
2437        mActivityStarter.setWindowManager(wm);
2438    }
2439
2440    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2441        mUsageStatsService = usageStatsManager;
2442    }
2443
2444    public void startObservingNativeCrashes() {
2445        final NativeCrashListener ncl = new NativeCrashListener(this);
2446        ncl.start();
2447    }
2448
2449    public IAppOpsService getAppOpsService() {
2450        return mAppOpsService;
2451    }
2452
2453    static class MemBinder extends Binder {
2454        ActivityManagerService mActivityManagerService;
2455        MemBinder(ActivityManagerService activityManagerService) {
2456            mActivityManagerService = activityManagerService;
2457        }
2458
2459        @Override
2460        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2461            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2462                    != PackageManager.PERMISSION_GRANTED) {
2463                pw.println("Permission Denial: can't dump meminfo from from pid="
2464                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2465                        + " without permission " + android.Manifest.permission.DUMP);
2466                return;
2467            }
2468
2469            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2470        }
2471    }
2472
2473    static class GraphicsBinder extends Binder {
2474        ActivityManagerService mActivityManagerService;
2475        GraphicsBinder(ActivityManagerService activityManagerService) {
2476            mActivityManagerService = activityManagerService;
2477        }
2478
2479        @Override
2480        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2481            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2482                    != PackageManager.PERMISSION_GRANTED) {
2483                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2484                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2485                        + " without permission " + android.Manifest.permission.DUMP);
2486                return;
2487            }
2488
2489            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2490        }
2491    }
2492
2493    static class DbBinder extends Binder {
2494        ActivityManagerService mActivityManagerService;
2495        DbBinder(ActivityManagerService activityManagerService) {
2496            mActivityManagerService = activityManagerService;
2497        }
2498
2499        @Override
2500        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2501            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2502                    != PackageManager.PERMISSION_GRANTED) {
2503                pw.println("Permission Denial: can't dump dbinfo from from pid="
2504                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2505                        + " without permission " + android.Manifest.permission.DUMP);
2506                return;
2507            }
2508
2509            mActivityManagerService.dumpDbInfo(fd, pw, args);
2510        }
2511    }
2512
2513    static class CpuBinder extends Binder {
2514        ActivityManagerService mActivityManagerService;
2515        CpuBinder(ActivityManagerService activityManagerService) {
2516            mActivityManagerService = activityManagerService;
2517        }
2518
2519        @Override
2520        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2521            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2522                    != PackageManager.PERMISSION_GRANTED) {
2523                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2524                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2525                        + " without permission " + android.Manifest.permission.DUMP);
2526                return;
2527            }
2528
2529            synchronized (mActivityManagerService.mProcessCpuTracker) {
2530                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2531                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2532                        SystemClock.uptimeMillis()));
2533            }
2534        }
2535    }
2536
2537    public static final class Lifecycle extends SystemService {
2538        private final ActivityManagerService mService;
2539
2540        public Lifecycle(Context context) {
2541            super(context);
2542            mService = new ActivityManagerService(context);
2543        }
2544
2545        @Override
2546        public void onStart() {
2547            mService.start();
2548        }
2549
2550        public ActivityManagerService getService() {
2551            return mService;
2552        }
2553    }
2554
2555    // Note: This method is invoked on the main thread but may need to attach various
2556    // handlers to other threads.  So take care to be explicit about the looper.
2557    public ActivityManagerService(Context systemContext) {
2558        mContext = systemContext;
2559        mFactoryTest = FactoryTest.getMode();
2560        mSystemThread = ActivityThread.currentActivityThread();
2561
2562        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2563
2564        mHandlerThread = new ServiceThread(TAG,
2565                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2566        mHandlerThread.start();
2567        mHandler = new MainHandler(mHandlerThread.getLooper());
2568        mUiHandler = new UiHandler();
2569
2570        /* static; one-time init here */
2571        if (sKillHandler == null) {
2572            sKillThread = new ServiceThread(TAG + ":kill",
2573                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2574            sKillThread.start();
2575            sKillHandler = new KillHandler(sKillThread.getLooper());
2576        }
2577
2578        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "foreground", BROADCAST_FG_TIMEOUT, false);
2580        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2581                "background", BROADCAST_BG_TIMEOUT, true);
2582        mBroadcastQueues[0] = mFgBroadcastQueue;
2583        mBroadcastQueues[1] = mBgBroadcastQueue;
2584
2585        mServices = new ActiveServices(this);
2586        mProviderMap = new ProviderMap(this);
2587        mAppErrors = new AppErrors(mContext, this);
2588
2589        // TODO: Move creation of battery stats service outside of activity manager service.
2590        File dataDir = Environment.getDataDirectory();
2591        File systemDir = new File(dataDir, "system");
2592        systemDir.mkdirs();
2593        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2594        mBatteryStatsService.getActiveStatistics().readLocked();
2595        mBatteryStatsService.scheduleWriteToDisk();
2596        mOnBattery = DEBUG_POWER ? true
2597                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2598        mBatteryStatsService.getActiveStatistics().setCallback(this);
2599
2600        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2601
2602        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2603        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2604                new IAppOpsCallback.Stub() {
2605                    @Override public void opChanged(int op, int uid, String packageName) {
2606                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2607                            if (mAppOpsService.checkOperation(op, uid, packageName)
2608                                    != AppOpsManager.MODE_ALLOWED) {
2609                                runInBackgroundDisabled(uid);
2610                            }
2611                        }
2612                    }
2613                });
2614
2615        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2616
2617        mUserController = new UserController(this);
2618
2619        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2620            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2621
2622        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2623
2624        mConfiguration.setToDefaults();
2625        mConfiguration.setLocales(LocaleList.getDefault());
2626
2627        mConfigurationSeq = mConfiguration.seq = 1;
2628        mProcessCpuTracker.init();
2629
2630        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2631        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2632        mStackSupervisor = new ActivityStackSupervisor(this);
2633        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2634        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2635
2636        mProcessCpuThread = new Thread("CpuTracker") {
2637            @Override
2638            public void run() {
2639                while (true) {
2640                    try {
2641                        try {
2642                            synchronized(this) {
2643                                final long now = SystemClock.uptimeMillis();
2644                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2645                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2646                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2647                                //        + ", write delay=" + nextWriteDelay);
2648                                if (nextWriteDelay < nextCpuDelay) {
2649                                    nextCpuDelay = nextWriteDelay;
2650                                }
2651                                if (nextCpuDelay > 0) {
2652                                    mProcessCpuMutexFree.set(true);
2653                                    this.wait(nextCpuDelay);
2654                                }
2655                            }
2656                        } catch (InterruptedException e) {
2657                        }
2658                        updateCpuStatsNow();
2659                    } catch (Exception e) {
2660                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2661                    }
2662                }
2663            }
2664        };
2665
2666        Watchdog.getInstance().addMonitor(this);
2667        Watchdog.getInstance().addThread(mHandler);
2668    }
2669
2670    public void setSystemServiceManager(SystemServiceManager mgr) {
2671        mSystemServiceManager = mgr;
2672    }
2673
2674    public void setInstaller(Installer installer) {
2675        mInstaller = installer;
2676    }
2677
2678    private void start() {
2679        Process.removeAllProcessGroups();
2680        mProcessCpuThread.start();
2681
2682        mBatteryStatsService.publish(mContext);
2683        mAppOpsService.publish(mContext);
2684        Slog.d("AppOps", "AppOpsService published");
2685        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2686    }
2687
2688    void onUserStoppedLocked(int userId) {
2689        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2690    }
2691
2692    public void initPowerManagement() {
2693        mStackSupervisor.initPowerManagement();
2694        mBatteryStatsService.initPowerManagement();
2695        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2696        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2697        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2698        mVoiceWakeLock.setReferenceCounted(false);
2699    }
2700
2701    @Override
2702    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2703            throws RemoteException {
2704        if (code == SYSPROPS_TRANSACTION) {
2705            // We need to tell all apps about the system property change.
2706            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2707            synchronized(this) {
2708                final int NP = mProcessNames.getMap().size();
2709                for (int ip=0; ip<NP; ip++) {
2710                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2711                    final int NA = apps.size();
2712                    for (int ia=0; ia<NA; ia++) {
2713                        ProcessRecord app = apps.valueAt(ia);
2714                        if (app.thread != null) {
2715                            procs.add(app.thread.asBinder());
2716                        }
2717                    }
2718                }
2719            }
2720
2721            int N = procs.size();
2722            for (int i=0; i<N; i++) {
2723                Parcel data2 = Parcel.obtain();
2724                try {
2725                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2726                } catch (RemoteException e) {
2727                }
2728                data2.recycle();
2729            }
2730        }
2731        try {
2732            return super.onTransact(code, data, reply, flags);
2733        } catch (RuntimeException e) {
2734            // The activity manager only throws security exceptions, so let's
2735            // log all others.
2736            if (!(e instanceof SecurityException)) {
2737                Slog.wtf(TAG, "Activity Manager Crash", e);
2738            }
2739            throw e;
2740        }
2741    }
2742
2743    void updateCpuStats() {
2744        final long now = SystemClock.uptimeMillis();
2745        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2746            return;
2747        }
2748        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2749            synchronized (mProcessCpuThread) {
2750                mProcessCpuThread.notify();
2751            }
2752        }
2753    }
2754
2755    void updateCpuStatsNow() {
2756        synchronized (mProcessCpuTracker) {
2757            mProcessCpuMutexFree.set(false);
2758            final long now = SystemClock.uptimeMillis();
2759            boolean haveNewCpuStats = false;
2760
2761            if (MONITOR_CPU_USAGE &&
2762                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2763                mLastCpuTime.set(now);
2764                mProcessCpuTracker.update();
2765                if (mProcessCpuTracker.hasGoodLastStats()) {
2766                    haveNewCpuStats = true;
2767                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2768                    //Slog.i(TAG, "Total CPU usage: "
2769                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2770
2771                    // Slog the cpu usage if the property is set.
2772                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2773                        int user = mProcessCpuTracker.getLastUserTime();
2774                        int system = mProcessCpuTracker.getLastSystemTime();
2775                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2776                        int irq = mProcessCpuTracker.getLastIrqTime();
2777                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2778                        int idle = mProcessCpuTracker.getLastIdleTime();
2779
2780                        int total = user + system + iowait + irq + softIrq + idle;
2781                        if (total == 0) total = 1;
2782
2783                        EventLog.writeEvent(EventLogTags.CPU,
2784                                ((user+system+iowait+irq+softIrq) * 100) / total,
2785                                (user * 100) / total,
2786                                (system * 100) / total,
2787                                (iowait * 100) / total,
2788                                (irq * 100) / total,
2789                                (softIrq * 100) / total);
2790                    }
2791                }
2792            }
2793
2794            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2795            synchronized(bstats) {
2796                synchronized(mPidsSelfLocked) {
2797                    if (haveNewCpuStats) {
2798                        if (bstats.startAddingCpuLocked()) {
2799                            int totalUTime = 0;
2800                            int totalSTime = 0;
2801                            final int N = mProcessCpuTracker.countStats();
2802                            for (int i=0; i<N; i++) {
2803                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2804                                if (!st.working) {
2805                                    continue;
2806                                }
2807                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2808                                totalUTime += st.rel_utime;
2809                                totalSTime += st.rel_stime;
2810                                if (pr != null) {
2811                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2812                                    if (ps == null || !ps.isActive()) {
2813                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2814                                                pr.info.uid, pr.processName);
2815                                    }
2816                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2817                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2818                                } else {
2819                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2820                                    if (ps == null || !ps.isActive()) {
2821                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2822                                                bstats.mapUid(st.uid), st.name);
2823                                    }
2824                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2825                                }
2826                            }
2827                            final int userTime = mProcessCpuTracker.getLastUserTime();
2828                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2829                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2830                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2831                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2832                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2833                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2834                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2835                        }
2836                    }
2837                }
2838
2839                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2840                    mLastWriteTime = now;
2841                    mBatteryStatsService.scheduleWriteToDisk();
2842                }
2843            }
2844        }
2845    }
2846
2847    @Override
2848    public void batteryNeedsCpuUpdate() {
2849        updateCpuStatsNow();
2850    }
2851
2852    @Override
2853    public void batteryPowerChanged(boolean onBattery) {
2854        // When plugging in, update the CPU stats first before changing
2855        // the plug state.
2856        updateCpuStatsNow();
2857        synchronized (this) {
2858            synchronized(mPidsSelfLocked) {
2859                mOnBattery = DEBUG_POWER ? true : onBattery;
2860            }
2861        }
2862    }
2863
2864    @Override
2865    public void batterySendBroadcast(Intent intent) {
2866        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2867                AppOpsManager.OP_NONE, null, false, false,
2868                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2869    }
2870
2871    /**
2872     * Initialize the application bind args. These are passed to each
2873     * process when the bindApplication() IPC is sent to the process. They're
2874     * lazily setup to make sure the services are running when they're asked for.
2875     */
2876    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2877        if (mAppBindArgs == null) {
2878            mAppBindArgs = new HashMap<>();
2879
2880            // Isolated processes won't get this optimization, so that we don't
2881            // violate the rules about which services they have access to.
2882            if (!isolated) {
2883                // Setup the application init args
2884                mAppBindArgs.put("package", ServiceManager.getService("package"));
2885                mAppBindArgs.put("window", ServiceManager.getService("window"));
2886                mAppBindArgs.put(Context.ALARM_SERVICE,
2887                        ServiceManager.getService(Context.ALARM_SERVICE));
2888            }
2889        }
2890        return mAppBindArgs;
2891    }
2892
2893    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2894        if (r == null || mFocusedActivity == r) {
2895            return false;
2896        }
2897
2898        if (!r.isFocusable()) {
2899            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2900            return false;
2901        }
2902
2903        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2904
2905        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2906        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2907                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2908        mDoingSetFocusedActivity = true;
2909
2910        final ActivityRecord last = mFocusedActivity;
2911        mFocusedActivity = r;
2912        if (r.task.isApplicationTask()) {
2913            if (mCurAppTimeTracker != r.appTimeTracker) {
2914                // We are switching app tracking.  Complete the current one.
2915                if (mCurAppTimeTracker != null) {
2916                    mCurAppTimeTracker.stop();
2917                    mHandler.obtainMessage(
2918                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2919                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2920                    mCurAppTimeTracker = null;
2921                }
2922                if (r.appTimeTracker != null) {
2923                    mCurAppTimeTracker = r.appTimeTracker;
2924                    startTimeTrackingFocusedActivityLocked();
2925                }
2926            } else {
2927                startTimeTrackingFocusedActivityLocked();
2928            }
2929        } else {
2930            r.appTimeTracker = null;
2931        }
2932        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2933        // TODO: Probably not, because we don't want to resume voice on switching
2934        // back to this activity
2935        if (r.task.voiceInteractor != null) {
2936            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2937        } else {
2938            finishRunningVoiceLocked();
2939            IVoiceInteractionSession session;
2940            if (last != null && ((session = last.task.voiceSession) != null
2941                    || (session = last.voiceSession) != null)) {
2942                // We had been in a voice interaction session, but now focused has
2943                // move to something different.  Just finish the session, we can't
2944                // return to it and retain the proper state and synchronization with
2945                // the voice interaction service.
2946                finishVoiceTask(session);
2947            }
2948        }
2949        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2950            mWindowManager.setFocusedApp(r.appToken, true);
2951        }
2952        applyUpdateLockStateLocked(r);
2953        applyUpdateVrModeLocked(r);
2954        if (mFocusedActivity.userId != mLastFocusedUserId) {
2955            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2956            mHandler.obtainMessage(
2957                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2958            mLastFocusedUserId = mFocusedActivity.userId;
2959        }
2960
2961        // Log a warning if the focused app is changed during the process. This could
2962        // indicate a problem of the focus setting logic!
2963        if (mFocusedActivity != r) Slog.w(TAG,
2964                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2965        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2966
2967        EventLogTags.writeAmFocusedActivity(
2968                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2969                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2970                reason);
2971        return true;
2972    }
2973
2974    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2975        if (mFocusedActivity != goingAway) {
2976            return;
2977        }
2978
2979        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2980        if (focusedStack != null) {
2981            final ActivityRecord top = focusedStack.topActivity();
2982            if (top != null && top.userId != mLastFocusedUserId) {
2983                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2984                mHandler.sendMessage(
2985                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2986                mLastFocusedUserId = top.userId;
2987            }
2988        }
2989
2990        // Try to move focus to another activity if possible.
2991        if (setFocusedActivityLocked(
2992                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2993            return;
2994        }
2995
2996        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2997                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2998        mFocusedActivity = null;
2999        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3000    }
3001
3002    @Override
3003    public void setFocusedStack(int stackId) {
3004        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3005        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3006        final long callingId = Binder.clearCallingIdentity();
3007        try {
3008            synchronized (this) {
3009                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3010                if (stack == null) {
3011                    return;
3012                }
3013                final ActivityRecord r = stack.topRunningActivityLocked();
3014                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3015                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3016                }
3017            }
3018        } finally {
3019            Binder.restoreCallingIdentity(callingId);
3020        }
3021    }
3022
3023    @Override
3024    public void setFocusedTask(int taskId) {
3025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3026        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3027        final long callingId = Binder.clearCallingIdentity();
3028        try {
3029            synchronized (this) {
3030                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3031                if (task == null) {
3032                    return;
3033                }
3034                final ActivityRecord r = task.topRunningActivityLocked();
3035                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3036                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3037                }
3038            }
3039        } finally {
3040            Binder.restoreCallingIdentity(callingId);
3041        }
3042    }
3043
3044    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3045    @Override
3046    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3047        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3048        synchronized (this) {
3049            if (listener != null) {
3050                mTaskStackListeners.register(listener);
3051            }
3052        }
3053    }
3054
3055    @Override
3056    public void notifyActivityDrawn(IBinder token) {
3057        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3058        synchronized (this) {
3059            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3060            if (r != null) {
3061                r.task.stack.notifyActivityDrawnLocked(r);
3062            }
3063        }
3064    }
3065
3066    final void applyUpdateLockStateLocked(ActivityRecord r) {
3067        // Modifications to the UpdateLock state are done on our handler, outside
3068        // the activity manager's locks.  The new state is determined based on the
3069        // state *now* of the relevant activity record.  The object is passed to
3070        // the handler solely for logging detail, not to be consulted/modified.
3071        final boolean nextState = r != null && r.immersive;
3072        mHandler.sendMessage(
3073                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3074    }
3075
3076    final void applyUpdateVrModeLocked(ActivityRecord r) {
3077        mHandler.sendMessage(
3078                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3079    }
3080
3081    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3082        mHandler.sendMessage(
3083                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3084    }
3085
3086    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3087        Message msg = Message.obtain();
3088        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3089        msg.obj = r.task.askedCompatMode ? null : r;
3090        mUiHandler.sendMessage(msg);
3091    }
3092
3093    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3094            String what, Object obj, ProcessRecord srcApp) {
3095        app.lastActivityTime = now;
3096
3097        if (app.activities.size() > 0) {
3098            // Don't want to touch dependent processes that are hosting activities.
3099            return index;
3100        }
3101
3102        int lrui = mLruProcesses.lastIndexOf(app);
3103        if (lrui < 0) {
3104            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3105                    + what + " " + obj + " from " + srcApp);
3106            return index;
3107        }
3108
3109        if (lrui >= index) {
3110            // Don't want to cause this to move dependent processes *back* in the
3111            // list as if they were less frequently used.
3112            return index;
3113        }
3114
3115        if (lrui >= mLruProcessActivityStart) {
3116            // Don't want to touch dependent processes that are hosting activities.
3117            return index;
3118        }
3119
3120        mLruProcesses.remove(lrui);
3121        if (index > 0) {
3122            index--;
3123        }
3124        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3125                + " in LRU list: " + app);
3126        mLruProcesses.add(index, app);
3127        return index;
3128    }
3129
3130    static void killProcessGroup(int uid, int pid) {
3131        if (sKillHandler != null) {
3132            sKillHandler.sendMessage(
3133                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3134        } else {
3135            Slog.w(TAG, "Asked to kill process group before system bringup!");
3136            Process.killProcessGroup(uid, pid);
3137        }
3138    }
3139
3140    final void removeLruProcessLocked(ProcessRecord app) {
3141        int lrui = mLruProcesses.lastIndexOf(app);
3142        if (lrui >= 0) {
3143            if (!app.killed) {
3144                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3145                Process.killProcessQuiet(app.pid);
3146                killProcessGroup(app.uid, app.pid);
3147            }
3148            if (lrui <= mLruProcessActivityStart) {
3149                mLruProcessActivityStart--;
3150            }
3151            if (lrui <= mLruProcessServiceStart) {
3152                mLruProcessServiceStart--;
3153            }
3154            mLruProcesses.remove(lrui);
3155        }
3156    }
3157
3158    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3159            ProcessRecord client) {
3160        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3161                || app.treatLikeActivity;
3162        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3163        if (!activityChange && hasActivity) {
3164            // The process has activities, so we are only allowing activity-based adjustments
3165            // to move it.  It should be kept in the front of the list with other
3166            // processes that have activities, and we don't want those to change their
3167            // order except due to activity operations.
3168            return;
3169        }
3170
3171        mLruSeq++;
3172        final long now = SystemClock.uptimeMillis();
3173        app.lastActivityTime = now;
3174
3175        // First a quick reject: if the app is already at the position we will
3176        // put it, then there is nothing to do.
3177        if (hasActivity) {
3178            final int N = mLruProcesses.size();
3179            if (N > 0 && mLruProcesses.get(N-1) == app) {
3180                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3181                return;
3182            }
3183        } else {
3184            if (mLruProcessServiceStart > 0
3185                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3186                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3187                return;
3188            }
3189        }
3190
3191        int lrui = mLruProcesses.lastIndexOf(app);
3192
3193        if (app.persistent && lrui >= 0) {
3194            // We don't care about the position of persistent processes, as long as
3195            // they are in the list.
3196            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3197            return;
3198        }
3199
3200        /* In progress: compute new position first, so we can avoid doing work
3201           if the process is not actually going to move.  Not yet working.
3202        int addIndex;
3203        int nextIndex;
3204        boolean inActivity = false, inService = false;
3205        if (hasActivity) {
3206            // Process has activities, put it at the very tipsy-top.
3207            addIndex = mLruProcesses.size();
3208            nextIndex = mLruProcessServiceStart;
3209            inActivity = true;
3210        } else if (hasService) {
3211            // Process has services, put it at the top of the service list.
3212            addIndex = mLruProcessActivityStart;
3213            nextIndex = mLruProcessServiceStart;
3214            inActivity = true;
3215            inService = true;
3216        } else  {
3217            // Process not otherwise of interest, it goes to the top of the non-service area.
3218            addIndex = mLruProcessServiceStart;
3219            if (client != null) {
3220                int clientIndex = mLruProcesses.lastIndexOf(client);
3221                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3222                        + app);
3223                if (clientIndex >= 0 && addIndex > clientIndex) {
3224                    addIndex = clientIndex;
3225                }
3226            }
3227            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3228        }
3229
3230        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3231                + mLruProcessActivityStart + "): " + app);
3232        */
3233
3234        if (lrui >= 0) {
3235            if (lrui < mLruProcessActivityStart) {
3236                mLruProcessActivityStart--;
3237            }
3238            if (lrui < mLruProcessServiceStart) {
3239                mLruProcessServiceStart--;
3240            }
3241            /*
3242            if (addIndex > lrui) {
3243                addIndex--;
3244            }
3245            if (nextIndex > lrui) {
3246                nextIndex--;
3247            }
3248            */
3249            mLruProcesses.remove(lrui);
3250        }
3251
3252        /*
3253        mLruProcesses.add(addIndex, app);
3254        if (inActivity) {
3255            mLruProcessActivityStart++;
3256        }
3257        if (inService) {
3258            mLruProcessActivityStart++;
3259        }
3260        */
3261
3262        int nextIndex;
3263        if (hasActivity) {
3264            final int N = mLruProcesses.size();
3265            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3266                // Process doesn't have activities, but has clients with
3267                // activities...  move it up, but one below the top (the top
3268                // should always have a real activity).
3269                if (DEBUG_LRU) Slog.d(TAG_LRU,
3270                        "Adding to second-top of LRU activity list: " + app);
3271                mLruProcesses.add(N - 1, app);
3272                // To keep it from spamming the LRU list (by making a bunch of clients),
3273                // we will push down any other entries owned by the app.
3274                final int uid = app.info.uid;
3275                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3276                    ProcessRecord subProc = mLruProcesses.get(i);
3277                    if (subProc.info.uid == uid) {
3278                        // We want to push this one down the list.  If the process after
3279                        // it is for the same uid, however, don't do so, because we don't
3280                        // want them internally to be re-ordered.
3281                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3282                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3283                                    "Pushing uid " + uid + " swapping at " + i + ": "
3284                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3285                            ProcessRecord tmp = mLruProcesses.get(i);
3286                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3287                            mLruProcesses.set(i - 1, tmp);
3288                            i--;
3289                        }
3290                    } else {
3291                        // A gap, we can stop here.
3292                        break;
3293                    }
3294                }
3295            } else {
3296                // Process has activities, put it at the very tipsy-top.
3297                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3298                mLruProcesses.add(app);
3299            }
3300            nextIndex = mLruProcessServiceStart;
3301        } else if (hasService) {
3302            // Process has services, put it at the top of the service list.
3303            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3304            mLruProcesses.add(mLruProcessActivityStart, app);
3305            nextIndex = mLruProcessServiceStart;
3306            mLruProcessActivityStart++;
3307        } else  {
3308            // Process not otherwise of interest, it goes to the top of the non-service area.
3309            int index = mLruProcessServiceStart;
3310            if (client != null) {
3311                // If there is a client, don't allow the process to be moved up higher
3312                // in the list than that client.
3313                int clientIndex = mLruProcesses.lastIndexOf(client);
3314                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3315                        + " when updating " + app);
3316                if (clientIndex <= lrui) {
3317                    // Don't allow the client index restriction to push it down farther in the
3318                    // list than it already is.
3319                    clientIndex = lrui;
3320                }
3321                if (clientIndex >= 0 && index > clientIndex) {
3322                    index = clientIndex;
3323                }
3324            }
3325            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3326            mLruProcesses.add(index, app);
3327            nextIndex = index-1;
3328            mLruProcessActivityStart++;
3329            mLruProcessServiceStart++;
3330        }
3331
3332        // If the app is currently using a content provider or service,
3333        // bump those processes as well.
3334        for (int j=app.connections.size()-1; j>=0; j--) {
3335            ConnectionRecord cr = app.connections.valueAt(j);
3336            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3337                    && cr.binding.service.app != null
3338                    && cr.binding.service.app.lruSeq != mLruSeq
3339                    && !cr.binding.service.app.persistent) {
3340                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3341                        "service connection", cr, app);
3342            }
3343        }
3344        for (int j=app.conProviders.size()-1; j>=0; j--) {
3345            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3346            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3347                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3348                        "provider reference", cpr, app);
3349            }
3350        }
3351    }
3352
3353    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3354        if (uid == Process.SYSTEM_UID) {
3355            // The system gets to run in any process.  If there are multiple
3356            // processes with the same uid, just pick the first (this
3357            // should never happen).
3358            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3359            if (procs == null) return null;
3360            final int procCount = procs.size();
3361            for (int i = 0; i < procCount; i++) {
3362                final int procUid = procs.keyAt(i);
3363                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3364                    // Don't use an app process or different user process for system component.
3365                    continue;
3366                }
3367                return procs.valueAt(i);
3368            }
3369        }
3370        ProcessRecord proc = mProcessNames.get(processName, uid);
3371        if (false && proc != null && !keepIfLarge
3372                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3373                && proc.lastCachedPss >= 4000) {
3374            // Turn this condition on to cause killing to happen regularly, for testing.
3375            if (proc.baseProcessTracker != null) {
3376                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3377            }
3378            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3379        } else if (proc != null && !keepIfLarge
3380                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3381                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3382            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3383            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3384                if (proc.baseProcessTracker != null) {
3385                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3386                }
3387                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3388            }
3389        }
3390        return proc;
3391    }
3392
3393    void notifyPackageUse(String packageName, int reason) {
3394        IPackageManager pm = AppGlobals.getPackageManager();
3395        try {
3396            pm.notifyPackageUse(packageName, reason);
3397        } catch (RemoteException e) {
3398        }
3399    }
3400
3401    boolean isNextTransitionForward() {
3402        int transit = mWindowManager.getPendingAppTransition();
3403        return transit == TRANSIT_ACTIVITY_OPEN
3404                || transit == TRANSIT_TASK_OPEN
3405                || transit == TRANSIT_TASK_TO_FRONT;
3406    }
3407
3408    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3409            String processName, String abiOverride, int uid, Runnable crashHandler) {
3410        synchronized(this) {
3411            ApplicationInfo info = new ApplicationInfo();
3412            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3413            // For isolated processes, the former contains the parent's uid and the latter the
3414            // actual uid of the isolated process.
3415            // In the special case introduced by this method (which is, starting an isolated
3416            // process directly from the SystemServer without an actual parent app process) the
3417            // closest thing to a parent's uid is SYSTEM_UID.
3418            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3419            // the |isolated| logic in the ProcessRecord constructor.
3420            info.uid = Process.SYSTEM_UID;
3421            info.processName = processName;
3422            info.className = entryPoint;
3423            info.packageName = "android";
3424            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3425                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3426                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3427                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3428                    crashHandler);
3429            return proc != null ? proc.pid : 0;
3430        }
3431    }
3432
3433    final ProcessRecord startProcessLocked(String processName,
3434            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3435            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3436            boolean isolated, boolean keepIfLarge) {
3437        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3438                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3439                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3440                null /* crashHandler */);
3441    }
3442
3443    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3444            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3445            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3446            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3447        long startTime = SystemClock.elapsedRealtime();
3448        ProcessRecord app;
3449        if (!isolated) {
3450            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3451            checkTime(startTime, "startProcess: after getProcessRecord");
3452
3453            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3454                // If we are in the background, then check to see if this process
3455                // is bad.  If so, we will just silently fail.
3456                if (mAppErrors.isBadProcessLocked(info)) {
3457                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3458                            + "/" + info.processName);
3459                    return null;
3460                }
3461            } else {
3462                // When the user is explicitly starting a process, then clear its
3463                // crash count so that we won't make it bad until they see at
3464                // least one crash dialog again, and make the process good again
3465                // if it had been bad.
3466                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3467                        + "/" + info.processName);
3468                mAppErrors.resetProcessCrashTimeLocked(info);
3469                if (mAppErrors.isBadProcessLocked(info)) {
3470                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3471                            UserHandle.getUserId(info.uid), info.uid,
3472                            info.processName);
3473                    mAppErrors.clearBadProcessLocked(info);
3474                    if (app != null) {
3475                        app.bad = false;
3476                    }
3477                }
3478            }
3479        } else {
3480            // If this is an isolated process, it can't re-use an existing process.
3481            app = null;
3482        }
3483
3484        // app launch boost for big.little configurations
3485        // use cpusets to migrate freshly launched tasks to big cores
3486        synchronized(ActivityManagerService.this) {
3487            nativeMigrateToBoost();
3488            mIsBoosted = true;
3489            mBoostStartTime = SystemClock.uptimeMillis();
3490            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3491            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3492        }
3493
3494        // We don't have to do anything more if:
3495        // (1) There is an existing application record; and
3496        // (2) The caller doesn't think it is dead, OR there is no thread
3497        //     object attached to it so we know it couldn't have crashed; and
3498        // (3) There is a pid assigned to it, so it is either starting or
3499        //     already running.
3500        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3501                + " app=" + app + " knownToBeDead=" + knownToBeDead
3502                + " thread=" + (app != null ? app.thread : null)
3503                + " pid=" + (app != null ? app.pid : -1));
3504        if (app != null && app.pid > 0) {
3505            if (!knownToBeDead || app.thread == null) {
3506                // We already have the app running, or are waiting for it to
3507                // come up (we have a pid but not yet its thread), so keep it.
3508                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3509                // If this is a new package in the process, add the package to the list
3510                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3511                checkTime(startTime, "startProcess: done, added package to proc");
3512                return app;
3513            }
3514
3515            // An application record is attached to a previous process,
3516            // clean it up now.
3517            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3518            checkTime(startTime, "startProcess: bad proc running, killing");
3519            killProcessGroup(app.uid, app.pid);
3520            handleAppDiedLocked(app, true, true);
3521            checkTime(startTime, "startProcess: done killing old proc");
3522        }
3523
3524        String hostingNameStr = hostingName != null
3525                ? hostingName.flattenToShortString() : null;
3526
3527        if (app == null) {
3528            checkTime(startTime, "startProcess: creating new process record");
3529            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3530            if (app == null) {
3531                Slog.w(TAG, "Failed making new process record for "
3532                        + processName + "/" + info.uid + " isolated=" + isolated);
3533                return null;
3534            }
3535            app.crashHandler = crashHandler;
3536            checkTime(startTime, "startProcess: done creating new process record");
3537        } else {
3538            // If this is a new package in the process, add the package to the list
3539            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3540            checkTime(startTime, "startProcess: added package to existing proc");
3541        }
3542
3543        // If the system is not ready yet, then hold off on starting this
3544        // process until it is.
3545        if (!mProcessesReady
3546                && !isAllowedWhileBooting(info)
3547                && !allowWhileBooting) {
3548            if (!mProcessesOnHold.contains(app)) {
3549                mProcessesOnHold.add(app);
3550            }
3551            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3552                    "System not ready, putting on hold: " + app);
3553            checkTime(startTime, "startProcess: returning with proc on hold");
3554            return app;
3555        }
3556
3557        checkTime(startTime, "startProcess: stepping in to startProcess");
3558        startProcessLocked(
3559                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3560        checkTime(startTime, "startProcess: done starting proc!");
3561        return (app.pid != 0) ? app : null;
3562    }
3563
3564    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3565        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3566    }
3567
3568    private final void startProcessLocked(ProcessRecord app,
3569            String hostingType, String hostingNameStr) {
3570        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3571                null /* entryPoint */, null /* entryPointArgs */);
3572    }
3573
3574    private final void startProcessLocked(ProcessRecord app, String hostingType,
3575            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3576        long startTime = SystemClock.elapsedRealtime();
3577        if (app.pid > 0 && app.pid != MY_PID) {
3578            checkTime(startTime, "startProcess: removing from pids map");
3579            synchronized (mPidsSelfLocked) {
3580                mPidsSelfLocked.remove(app.pid);
3581                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3582            }
3583            checkTime(startTime, "startProcess: done removing from pids map");
3584            app.setPid(0);
3585        }
3586
3587        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3588                "startProcessLocked removing on hold: " + app);
3589        mProcessesOnHold.remove(app);
3590
3591        checkTime(startTime, "startProcess: starting to update cpu stats");
3592        updateCpuStats();
3593        checkTime(startTime, "startProcess: done updating cpu stats");
3594
3595        try {
3596            try {
3597                final int userId = UserHandle.getUserId(app.uid);
3598                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3599            } catch (RemoteException e) {
3600                throw e.rethrowAsRuntimeException();
3601            }
3602
3603            int uid = app.uid;
3604            int[] gids = null;
3605            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3606            if (!app.isolated) {
3607                int[] permGids = null;
3608                try {
3609                    checkTime(startTime, "startProcess: getting gids from package manager");
3610                    final IPackageManager pm = AppGlobals.getPackageManager();
3611                    permGids = pm.getPackageGids(app.info.packageName,
3612                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3613                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3614                            MountServiceInternal.class);
3615                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3616                            app.info.packageName);
3617                } catch (RemoteException e) {
3618                    throw e.rethrowAsRuntimeException();
3619                }
3620
3621                /*
3622                 * Add shared application and profile GIDs so applications can share some
3623                 * resources like shared libraries and access user-wide resources
3624                 */
3625                if (ArrayUtils.isEmpty(permGids)) {
3626                    gids = new int[2];
3627                } else {
3628                    gids = new int[permGids.length + 2];
3629                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3630                }
3631                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3632                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3633            }
3634            checkTime(startTime, "startProcess: building args");
3635            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3636                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3637                        && mTopComponent != null
3638                        && app.processName.equals(mTopComponent.getPackageName())) {
3639                    uid = 0;
3640                }
3641                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3642                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3643                    uid = 0;
3644                }
3645            }
3646            int debugFlags = 0;
3647            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3648                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3649                // Also turn on CheckJNI for debuggable apps. It's quite
3650                // awkward to turn on otherwise.
3651                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3652            }
3653            // Run the app in safe mode if its manifest requests so or the
3654            // system is booted in safe mode.
3655            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3656                mSafeMode == true) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3658            }
3659            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3660                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3661            }
3662            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3663            if ("true".equals(genDebugInfoProperty)) {
3664                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3665            }
3666            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3667                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3668            }
3669            if ("1".equals(SystemProperties.get("debug.assert"))) {
3670                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3671            }
3672            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3673                // Enable all debug flags required by the native debugger.
3674                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3675                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3676                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3677                mNativeDebuggingApp = null;
3678            }
3679
3680            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3681            if (requiredAbi == null) {
3682                requiredAbi = Build.SUPPORTED_ABIS[0];
3683            }
3684
3685            String instructionSet = null;
3686            if (app.info.primaryCpuAbi != null) {
3687                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3688            }
3689
3690            app.gids = gids;
3691            app.requiredAbi = requiredAbi;
3692            app.instructionSet = instructionSet;
3693
3694            // Start the process.  It will either succeed and return a result containing
3695            // the PID of the new process, or else throw a RuntimeException.
3696            boolean isActivityProcess = (entryPoint == null);
3697            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3698            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3699                    app.processName);
3700            checkTime(startTime, "startProcess: asking zygote to start proc");
3701            Process.ProcessStartResult startResult = Process.start(entryPoint,
3702                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3703                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3704                    app.info.dataDir, entryPointArgs);
3705            checkTime(startTime, "startProcess: returned from zygote!");
3706            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3707
3708            if (app.isolated) {
3709                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3710            }
3711            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3712            checkTime(startTime, "startProcess: done updating battery stats");
3713
3714            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3715                    UserHandle.getUserId(uid), startResult.pid, uid,
3716                    app.processName, hostingType,
3717                    hostingNameStr != null ? hostingNameStr : "");
3718
3719            try {
3720                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3721                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3722            } catch (RemoteException ex) {
3723                // Ignore
3724            }
3725
3726            if (app.persistent) {
3727                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3728            }
3729
3730            checkTime(startTime, "startProcess: building log message");
3731            StringBuilder buf = mStringBuilder;
3732            buf.setLength(0);
3733            buf.append("Start proc ");
3734            buf.append(startResult.pid);
3735            buf.append(':');
3736            buf.append(app.processName);
3737            buf.append('/');
3738            UserHandle.formatUid(buf, uid);
3739            if (!isActivityProcess) {
3740                buf.append(" [");
3741                buf.append(entryPoint);
3742                buf.append("]");
3743            }
3744            buf.append(" for ");
3745            buf.append(hostingType);
3746            if (hostingNameStr != null) {
3747                buf.append(" ");
3748                buf.append(hostingNameStr);
3749            }
3750            Slog.i(TAG, buf.toString());
3751            app.setPid(startResult.pid);
3752            app.usingWrapper = startResult.usingWrapper;
3753            app.removed = false;
3754            app.killed = false;
3755            app.killedByAm = false;
3756            checkTime(startTime, "startProcess: starting to update pids map");
3757            synchronized (mPidsSelfLocked) {
3758                this.mPidsSelfLocked.put(startResult.pid, app);
3759                if (isActivityProcess) {
3760                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3761                    msg.obj = app;
3762                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3763                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3764                }
3765            }
3766            checkTime(startTime, "startProcess: done updating pids map");
3767        } catch (RuntimeException e) {
3768            Slog.e(TAG, "Failure starting process " + app.processName, e);
3769
3770            // Something went very wrong while trying to start this process; one
3771            // common case is when the package is frozen due to an active
3772            // upgrade. To recover, clean up any active bookkeeping related to
3773            // starting this process. (We already invoked this method once when
3774            // the package was initially frozen through KILL_APPLICATION_MSG, so
3775            // it doesn't hurt to use it again.)
3776            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3777                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3778        }
3779    }
3780
3781    void updateUsageStats(ActivityRecord component, boolean resumed) {
3782        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3783                "updateUsageStats: comp=" + component + "res=" + resumed);
3784        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3785        if (resumed) {
3786            if (mUsageStatsService != null) {
3787                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3788                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3789            }
3790            synchronized (stats) {
3791                stats.noteActivityResumedLocked(component.app.uid);
3792            }
3793        } else {
3794            if (mUsageStatsService != null) {
3795                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3796                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3797            }
3798            synchronized (stats) {
3799                stats.noteActivityPausedLocked(component.app.uid);
3800            }
3801        }
3802    }
3803
3804    Intent getHomeIntent() {
3805        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3806        intent.setComponent(mTopComponent);
3807        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3808        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3809            intent.addCategory(Intent.CATEGORY_HOME);
3810        }
3811        return intent;
3812    }
3813
3814    boolean startHomeActivityLocked(int userId, String reason) {
3815        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3816                && mTopAction == null) {
3817            // We are running in factory test mode, but unable to find
3818            // the factory test app, so just sit around displaying the
3819            // error message and don't try to start anything.
3820            return false;
3821        }
3822        Intent intent = getHomeIntent();
3823        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3824        if (aInfo != null) {
3825            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3826            // Don't do this if the home app is currently being
3827            // instrumented.
3828            aInfo = new ActivityInfo(aInfo);
3829            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3830            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3831                    aInfo.applicationInfo.uid, true);
3832            if (app == null || app.instrumentationClass == null) {
3833                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3834                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3835            }
3836        } else {
3837            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3838        }
3839
3840        return true;
3841    }
3842
3843    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3844        ActivityInfo ai = null;
3845        ComponentName comp = intent.getComponent();
3846        try {
3847            if (comp != null) {
3848                // Factory test.
3849                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3850            } else {
3851                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3852                        intent,
3853                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3854                        flags, userId);
3855
3856                if (info != null) {
3857                    ai = info.activityInfo;
3858                }
3859            }
3860        } catch (RemoteException e) {
3861            // ignore
3862        }
3863
3864        return ai;
3865    }
3866
3867    /**
3868     * Starts the "new version setup screen" if appropriate.
3869     */
3870    void startSetupActivityLocked() {
3871        // Only do this once per boot.
3872        if (mCheckedForSetup) {
3873            return;
3874        }
3875
3876        // We will show this screen if the current one is a different
3877        // version than the last one shown, and we are not running in
3878        // low-level factory test mode.
3879        final ContentResolver resolver = mContext.getContentResolver();
3880        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3881                Settings.Global.getInt(resolver,
3882                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3883            mCheckedForSetup = true;
3884
3885            // See if we should be showing the platform update setup UI.
3886            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3887            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3888                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3889            if (!ris.isEmpty()) {
3890                final ResolveInfo ri = ris.get(0);
3891                String vers = ri.activityInfo.metaData != null
3892                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3893                        : null;
3894                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3895                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3896                            Intent.METADATA_SETUP_VERSION);
3897                }
3898                String lastVers = Settings.Secure.getString(
3899                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3900                if (vers != null && !vers.equals(lastVers)) {
3901                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3902                    intent.setComponent(new ComponentName(
3903                            ri.activityInfo.packageName, ri.activityInfo.name));
3904                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3905                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3906                            null, 0, 0, 0, null, false, false, null, null, null);
3907                }
3908            }
3909        }
3910    }
3911
3912    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3913        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3914    }
3915
3916    void enforceNotIsolatedCaller(String caller) {
3917        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3918            throw new SecurityException("Isolated process not allowed to call " + caller);
3919        }
3920    }
3921
3922    void enforceShellRestriction(String restriction, int userHandle) {
3923        if (Binder.getCallingUid() == Process.SHELL_UID) {
3924            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3925                throw new SecurityException("Shell does not have permission to access user "
3926                        + userHandle);
3927            }
3928        }
3929    }
3930
3931    @Override
3932    public int getFrontActivityScreenCompatMode() {
3933        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3934        synchronized (this) {
3935            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3936        }
3937    }
3938
3939    @Override
3940    public void setFrontActivityScreenCompatMode(int mode) {
3941        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3942                "setFrontActivityScreenCompatMode");
3943        synchronized (this) {
3944            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3945        }
3946    }
3947
3948    @Override
3949    public int getPackageScreenCompatMode(String packageName) {
3950        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3951        synchronized (this) {
3952            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3953        }
3954    }
3955
3956    @Override
3957    public void setPackageScreenCompatMode(String packageName, int mode) {
3958        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3959                "setPackageScreenCompatMode");
3960        synchronized (this) {
3961            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3962        }
3963    }
3964
3965    @Override
3966    public boolean getPackageAskScreenCompat(String packageName) {
3967        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3968        synchronized (this) {
3969            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3970        }
3971    }
3972
3973    @Override
3974    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3975        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3976                "setPackageAskScreenCompat");
3977        synchronized (this) {
3978            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3979        }
3980    }
3981
3982    private boolean hasUsageStatsPermission(String callingPackage) {
3983        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3984                Binder.getCallingUid(), callingPackage);
3985        if (mode == AppOpsManager.MODE_DEFAULT) {
3986            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3987                    == PackageManager.PERMISSION_GRANTED;
3988        }
3989        return mode == AppOpsManager.MODE_ALLOWED;
3990    }
3991
3992    @Override
3993    public int getPackageProcessState(String packageName, String callingPackage) {
3994        if (!hasUsageStatsPermission(callingPackage)) {
3995            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3996                    "getPackageProcessState");
3997        }
3998
3999        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4000        synchronized (this) {
4001            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4002                final ProcessRecord proc = mLruProcesses.get(i);
4003                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4004                        || procState > proc.setProcState) {
4005                    boolean found = false;
4006                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4007                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4008                            procState = proc.setProcState;
4009                            found = true;
4010                        }
4011                    }
4012                    if (proc.pkgDeps != null && !found) {
4013                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4014                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4015                                procState = proc.setProcState;
4016                                break;
4017                            }
4018                        }
4019                    }
4020                }
4021            }
4022        }
4023        return procState;
4024    }
4025
4026    @Override
4027    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4028        synchronized (this) {
4029            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4030            if (app == null) {
4031                return false;
4032            }
4033            if (app.trimMemoryLevel < level && app.thread != null &&
4034                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4035                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4036                try {
4037                    app.thread.scheduleTrimMemory(level);
4038                    app.trimMemoryLevel = level;
4039                    return true;
4040                } catch (RemoteException e) {
4041                    // Fallthrough to failure case.
4042                }
4043            }
4044        }
4045        return false;
4046    }
4047
4048    private void dispatchProcessesChanged() {
4049        int N;
4050        synchronized (this) {
4051            N = mPendingProcessChanges.size();
4052            if (mActiveProcessChanges.length < N) {
4053                mActiveProcessChanges = new ProcessChangeItem[N];
4054            }
4055            mPendingProcessChanges.toArray(mActiveProcessChanges);
4056            mPendingProcessChanges.clear();
4057            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4058                    "*** Delivering " + N + " process changes");
4059        }
4060
4061        int i = mProcessObservers.beginBroadcast();
4062        while (i > 0) {
4063            i--;
4064            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4065            if (observer != null) {
4066                try {
4067                    for (int j=0; j<N; j++) {
4068                        ProcessChangeItem item = mActiveProcessChanges[j];
4069                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4070                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4071                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4072                                    + item.uid + ": " + item.foregroundActivities);
4073                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4074                                    item.foregroundActivities);
4075                        }
4076                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4077                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4078                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4079                                    + ": " + item.processState);
4080                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4081                        }
4082                    }
4083                } catch (RemoteException e) {
4084                }
4085            }
4086        }
4087        mProcessObservers.finishBroadcast();
4088
4089        synchronized (this) {
4090            for (int j=0; j<N; j++) {
4091                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4092            }
4093        }
4094    }
4095
4096    private void dispatchProcessDied(int pid, int uid) {
4097        int i = mProcessObservers.beginBroadcast();
4098        while (i > 0) {
4099            i--;
4100            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4101            if (observer != null) {
4102                try {
4103                    observer.onProcessDied(pid, uid);
4104                } catch (RemoteException e) {
4105                }
4106            }
4107        }
4108        mProcessObservers.finishBroadcast();
4109    }
4110
4111    private void dispatchUidsChanged() {
4112        int N;
4113        synchronized (this) {
4114            N = mPendingUidChanges.size();
4115            if (mActiveUidChanges.length < N) {
4116                mActiveUidChanges = new UidRecord.ChangeItem[N];
4117            }
4118            for (int i=0; i<N; i++) {
4119                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4120                mActiveUidChanges[i] = change;
4121                if (change.uidRecord != null) {
4122                    change.uidRecord.pendingChange = null;
4123                    change.uidRecord = null;
4124                }
4125            }
4126            mPendingUidChanges.clear();
4127            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4128                    "*** Delivering " + N + " uid changes");
4129        }
4130
4131        if (mLocalPowerManager != null) {
4132            for (int j=0; j<N; j++) {
4133                UidRecord.ChangeItem item = mActiveUidChanges[j];
4134                if (item.change == UidRecord.CHANGE_GONE
4135                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4136                    mLocalPowerManager.uidGone(item.uid);
4137                } else {
4138                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4139                }
4140            }
4141        }
4142
4143        int i = mUidObservers.beginBroadcast();
4144        while (i > 0) {
4145            i--;
4146            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4147            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4148            if (observer != null) {
4149                try {
4150                    for (int j=0; j<N; j++) {
4151                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4152                        final int change = item.change;
4153                        UidRecord validateUid = null;
4154                        if (VALIDATE_UID_STATES && i == 0) {
4155                            validateUid = mValidateUids.get(item.uid);
4156                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4157                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4158                                validateUid = new UidRecord(item.uid);
4159                                mValidateUids.put(item.uid, validateUid);
4160                            }
4161                        }
4162                        if (change == UidRecord.CHANGE_IDLE
4163                                || change == UidRecord.CHANGE_GONE_IDLE) {
4164                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4165                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4166                                        "UID idle uid=" + item.uid);
4167                                observer.onUidIdle(item.uid);
4168                            }
4169                            if (VALIDATE_UID_STATES && i == 0) {
4170                                if (validateUid != null) {
4171                                    validateUid.idle = true;
4172                                }
4173                            }
4174                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4175                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4176                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4177                                        "UID active uid=" + item.uid);
4178                                observer.onUidActive(item.uid);
4179                            }
4180                            if (VALIDATE_UID_STATES && i == 0) {
4181                                validateUid.idle = false;
4182                            }
4183                        }
4184                        if (change == UidRecord.CHANGE_GONE
4185                                || change == UidRecord.CHANGE_GONE_IDLE) {
4186                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4187                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4188                                        "UID gone uid=" + item.uid);
4189                                observer.onUidGone(item.uid);
4190                            }
4191                            if (VALIDATE_UID_STATES && i == 0) {
4192                                if (validateUid != null) {
4193                                    mValidateUids.remove(item.uid);
4194                                }
4195                            }
4196                        } else {
4197                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4198                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4199                                        "UID CHANGED uid=" + item.uid
4200                                                + ": " + item.processState);
4201                                observer.onUidStateChanged(item.uid, item.processState);
4202                            }
4203                            if (VALIDATE_UID_STATES && i == 0) {
4204                                validateUid.curProcState = validateUid.setProcState
4205                                        = item.processState;
4206                            }
4207                        }
4208                    }
4209                } catch (RemoteException e) {
4210                }
4211            }
4212        }
4213        mUidObservers.finishBroadcast();
4214
4215        synchronized (this) {
4216            for (int j=0; j<N; j++) {
4217                mAvailUidChanges.add(mActiveUidChanges[j]);
4218            }
4219        }
4220    }
4221
4222    @Override
4223    public final int startActivity(IApplicationThread caller, String callingPackage,
4224            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4225            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4226        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4227                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4228                UserHandle.getCallingUserId());
4229    }
4230
4231    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4232        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4233        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4234                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4235                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4236
4237        // TODO: Switch to user app stacks here.
4238        String mimeType = intent.getType();
4239        final Uri data = intent.getData();
4240        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4241            mimeType = getProviderMimeType(data, userId);
4242        }
4243        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4244
4245        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4246        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4247                null, 0, 0, null, null, null, null, false, userId, container, null);
4248    }
4249
4250    @Override
4251    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4252            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4253            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4254        enforceNotIsolatedCaller("startActivity");
4255        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4256                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4257        // TODO: Switch to user app stacks here.
4258        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4259                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4260                profilerInfo, null, null, bOptions, false, userId, null, null);
4261    }
4262
4263    @Override
4264    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4265            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4266            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4267            int userId) {
4268
4269        // This is very dangerous -- it allows you to perform a start activity (including
4270        // permission grants) as any app that may launch one of your own activities.  So
4271        // we will only allow this to be done from activities that are part of the core framework,
4272        // and then only when they are running as the system.
4273        final ActivityRecord sourceRecord;
4274        final int targetUid;
4275        final String targetPackage;
4276        synchronized (this) {
4277            if (resultTo == null) {
4278                throw new SecurityException("Must be called from an activity");
4279            }
4280            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4281            if (sourceRecord == null) {
4282                throw new SecurityException("Called with bad activity token: " + resultTo);
4283            }
4284            if (!sourceRecord.info.packageName.equals("android")) {
4285                throw new SecurityException(
4286                        "Must be called from an activity that is declared in the android package");
4287            }
4288            if (sourceRecord.app == null) {
4289                throw new SecurityException("Called without a process attached to activity");
4290            }
4291            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4292                // This is still okay, as long as this activity is running under the
4293                // uid of the original calling activity.
4294                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4295                    throw new SecurityException(
4296                            "Calling activity in uid " + sourceRecord.app.uid
4297                                    + " must be system uid or original calling uid "
4298                                    + sourceRecord.launchedFromUid);
4299                }
4300            }
4301            if (ignoreTargetSecurity) {
4302                if (intent.getComponent() == null) {
4303                    throw new SecurityException(
4304                            "Component must be specified with ignoreTargetSecurity");
4305                }
4306                if (intent.getSelector() != null) {
4307                    throw new SecurityException(
4308                            "Selector not allowed with ignoreTargetSecurity");
4309                }
4310            }
4311            targetUid = sourceRecord.launchedFromUid;
4312            targetPackage = sourceRecord.launchedFromPackage;
4313        }
4314
4315        if (userId == UserHandle.USER_NULL) {
4316            userId = UserHandle.getUserId(sourceRecord.app.uid);
4317        }
4318
4319        // TODO: Switch to user app stacks here.
4320        try {
4321            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4322                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4323                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4324            return ret;
4325        } catch (SecurityException e) {
4326            // XXX need to figure out how to propagate to original app.
4327            // A SecurityException here is generally actually a fault of the original
4328            // calling activity (such as a fairly granting permissions), so propagate it
4329            // back to them.
4330            /*
4331            StringBuilder msg = new StringBuilder();
4332            msg.append("While launching");
4333            msg.append(intent.toString());
4334            msg.append(": ");
4335            msg.append(e.getMessage());
4336            */
4337            throw e;
4338        }
4339    }
4340
4341    @Override
4342    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4343            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4344            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4345        enforceNotIsolatedCaller("startActivityAndWait");
4346        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4347                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4348        WaitResult res = new WaitResult();
4349        // TODO: Switch to user app stacks here.
4350        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4351                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4352                bOptions, false, userId, null, null);
4353        return res;
4354    }
4355
4356    @Override
4357    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359            int startFlags, Configuration config, Bundle bOptions, int userId) {
4360        enforceNotIsolatedCaller("startActivityWithConfig");
4361        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4362                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4363        // TODO: Switch to user app stacks here.
4364        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4365                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4366                null, null, config, bOptions, false, userId, null, null);
4367        return ret;
4368    }
4369
4370    @Override
4371    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4372            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4373            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4374            throws TransactionTooLargeException {
4375        enforceNotIsolatedCaller("startActivityIntentSender");
4376        // Refuse possible leaked file descriptors
4377        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4378            throw new IllegalArgumentException("File descriptors passed in Intent");
4379        }
4380
4381        IIntentSender sender = intent.getTarget();
4382        if (!(sender instanceof PendingIntentRecord)) {
4383            throw new IllegalArgumentException("Bad PendingIntent object");
4384        }
4385
4386        PendingIntentRecord pir = (PendingIntentRecord)sender;
4387
4388        synchronized (this) {
4389            // If this is coming from the currently resumed activity, it is
4390            // effectively saying that app switches are allowed at this point.
4391            final ActivityStack stack = getFocusedStack();
4392            if (stack.mResumedActivity != null &&
4393                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4394                mAppSwitchesAllowedTime = 0;
4395            }
4396        }
4397        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4398                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4399        return ret;
4400    }
4401
4402    @Override
4403    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4404            Intent intent, String resolvedType, IVoiceInteractionSession session,
4405            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4406            Bundle bOptions, int userId) {
4407        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4408                != PackageManager.PERMISSION_GRANTED) {
4409            String msg = "Permission Denial: startVoiceActivity() from pid="
4410                    + Binder.getCallingPid()
4411                    + ", uid=" + Binder.getCallingUid()
4412                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4413            Slog.w(TAG, msg);
4414            throw new SecurityException(msg);
4415        }
4416        if (session == null || interactor == null) {
4417            throw new NullPointerException("null session or interactor");
4418        }
4419        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4420                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4421        // TODO: Switch to user app stacks here.
4422        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4423                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4424                null, bOptions, false, userId, null, null);
4425    }
4426
4427    @Override
4428    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4429            throws RemoteException {
4430        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4431        synchronized (this) {
4432            ActivityRecord activity = getFocusedStack().topActivity();
4433            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4434                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4435            }
4436            if (mRunningVoice != null || activity.task.voiceSession != null
4437                    || activity.voiceSession != null) {
4438                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4439                return;
4440            }
4441            if (activity.pendingVoiceInteractionStart) {
4442                Slog.w(TAG, "Pending start of voice interaction already.");
4443                return;
4444            }
4445            activity.pendingVoiceInteractionStart = true;
4446        }
4447        LocalServices.getService(VoiceInteractionManagerInternal.class)
4448                .startLocalVoiceInteraction(callingActivity, options);
4449    }
4450
4451    @Override
4452    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4453        LocalServices.getService(VoiceInteractionManagerInternal.class)
4454                .stopLocalVoiceInteraction(callingActivity);
4455    }
4456
4457    @Override
4458    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4459        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4460                .supportsLocalVoiceInteraction();
4461    }
4462
4463    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4464            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4465        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4466        if (activityToCallback == null) return;
4467        activityToCallback.setVoiceSessionLocked(voiceSession);
4468
4469        // Inform the activity
4470        try {
4471            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4472                    voiceInteractor);
4473            long token = Binder.clearCallingIdentity();
4474            try {
4475                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4476            } finally {
4477                Binder.restoreCallingIdentity(token);
4478            }
4479            // TODO: VI Should we cache the activity so that it's easier to find later
4480            // rather than scan through all the stacks and activities?
4481        } catch (RemoteException re) {
4482            activityToCallback.clearVoiceSessionLocked();
4483            // TODO: VI Should this terminate the voice session?
4484        }
4485    }
4486
4487    @Override
4488    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4489        synchronized (this) {
4490            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4491                if (keepAwake) {
4492                    mVoiceWakeLock.acquire();
4493                } else {
4494                    mVoiceWakeLock.release();
4495                }
4496            }
4497        }
4498    }
4499
4500    @Override
4501    public boolean startNextMatchingActivity(IBinder callingActivity,
4502            Intent intent, Bundle bOptions) {
4503        // Refuse possible leaked file descriptors
4504        if (intent != null && intent.hasFileDescriptors() == true) {
4505            throw new IllegalArgumentException("File descriptors passed in Intent");
4506        }
4507        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4508
4509        synchronized (this) {
4510            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4511            if (r == null) {
4512                ActivityOptions.abort(options);
4513                return false;
4514            }
4515            if (r.app == null || r.app.thread == null) {
4516                // The caller is not running...  d'oh!
4517                ActivityOptions.abort(options);
4518                return false;
4519            }
4520            intent = new Intent(intent);
4521            // The caller is not allowed to change the data.
4522            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4523            // And we are resetting to find the next component...
4524            intent.setComponent(null);
4525
4526            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4527
4528            ActivityInfo aInfo = null;
4529            try {
4530                List<ResolveInfo> resolves =
4531                    AppGlobals.getPackageManager().queryIntentActivities(
4532                            intent, r.resolvedType,
4533                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4534                            UserHandle.getCallingUserId()).getList();
4535
4536                // Look for the original activity in the list...
4537                final int N = resolves != null ? resolves.size() : 0;
4538                for (int i=0; i<N; i++) {
4539                    ResolveInfo rInfo = resolves.get(i);
4540                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4541                            && rInfo.activityInfo.name.equals(r.info.name)) {
4542                        // We found the current one...  the next matching is
4543                        // after it.
4544                        i++;
4545                        if (i<N) {
4546                            aInfo = resolves.get(i).activityInfo;
4547                        }
4548                        if (debug) {
4549                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4550                                    + "/" + r.info.name);
4551                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4552                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4553                        }
4554                        break;
4555                    }
4556                }
4557            } catch (RemoteException e) {
4558            }
4559
4560            if (aInfo == null) {
4561                // Nobody who is next!
4562                ActivityOptions.abort(options);
4563                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4564                return false;
4565            }
4566
4567            intent.setComponent(new ComponentName(
4568                    aInfo.applicationInfo.packageName, aInfo.name));
4569            intent.setFlags(intent.getFlags()&~(
4570                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4571                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4572                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4573                    Intent.FLAG_ACTIVITY_NEW_TASK));
4574
4575            // Okay now we need to start the new activity, replacing the
4576            // currently running activity.  This is a little tricky because
4577            // we want to start the new one as if the current one is finished,
4578            // but not finish the current one first so that there is no flicker.
4579            // And thus...
4580            final boolean wasFinishing = r.finishing;
4581            r.finishing = true;
4582
4583            // Propagate reply information over to the new activity.
4584            final ActivityRecord resultTo = r.resultTo;
4585            final String resultWho = r.resultWho;
4586            final int requestCode = r.requestCode;
4587            r.resultTo = null;
4588            if (resultTo != null) {
4589                resultTo.removeResultsLocked(r, resultWho, requestCode);
4590            }
4591
4592            final long origId = Binder.clearCallingIdentity();
4593            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4594                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4595                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4596                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4597                    false, false, null, null, null);
4598            Binder.restoreCallingIdentity(origId);
4599
4600            r.finishing = wasFinishing;
4601            if (res != ActivityManager.START_SUCCESS) {
4602                return false;
4603            }
4604            return true;
4605        }
4606    }
4607
4608    @Override
4609    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4610        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4611            String msg = "Permission Denial: startActivityFromRecents called without " +
4612                    START_TASKS_FROM_RECENTS;
4613            Slog.w(TAG, msg);
4614            throw new SecurityException(msg);
4615        }
4616        final long origId = Binder.clearCallingIdentity();
4617        try {
4618            synchronized (this) {
4619                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4620            }
4621        } finally {
4622            Binder.restoreCallingIdentity(origId);
4623        }
4624    }
4625
4626    final int startActivityInPackage(int uid, String callingPackage,
4627            Intent intent, String resolvedType, IBinder resultTo,
4628            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4629            IActivityContainer container, TaskRecord inTask) {
4630
4631        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4632                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4633
4634        // TODO: Switch to user app stacks here.
4635        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4636                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4637                null, null, null, bOptions, false, userId, container, inTask);
4638        return ret;
4639    }
4640
4641    @Override
4642    public final int startActivities(IApplicationThread caller, String callingPackage,
4643            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4644            int userId) {
4645        enforceNotIsolatedCaller("startActivities");
4646        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4647                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4648        // TODO: Switch to user app stacks here.
4649        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4650                resolvedTypes, resultTo, bOptions, userId);
4651        return ret;
4652    }
4653
4654    final int startActivitiesInPackage(int uid, String callingPackage,
4655            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4656            Bundle bOptions, int userId) {
4657
4658        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4659                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4660        // TODO: Switch to user app stacks here.
4661        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4662                resultTo, bOptions, userId);
4663        return ret;
4664    }
4665
4666    @Override
4667    public void reportActivityFullyDrawn(IBinder token) {
4668        synchronized (this) {
4669            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4670            if (r == null) {
4671                return;
4672            }
4673            r.reportFullyDrawnLocked();
4674        }
4675    }
4676
4677    @Override
4678    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4679        synchronized (this) {
4680            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4681            if (r == null) {
4682                return;
4683            }
4684            TaskRecord task = r.task;
4685            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4686                // Fixed screen orientation isn't supported when activities aren't in full screen
4687                // mode.
4688                return;
4689            }
4690            final long origId = Binder.clearCallingIdentity();
4691            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4692            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4693                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4694            if (config != null) {
4695                r.frozenBeforeDestroy = true;
4696                if (!updateConfigurationLocked(config, r, false)) {
4697                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4698                }
4699            }
4700            Binder.restoreCallingIdentity(origId);
4701        }
4702    }
4703
4704    @Override
4705    public int getRequestedOrientation(IBinder token) {
4706        synchronized (this) {
4707            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4708            if (r == null) {
4709                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4710            }
4711            return mWindowManager.getAppOrientation(r.appToken);
4712        }
4713    }
4714
4715    /**
4716     * This is the internal entry point for handling Activity.finish().
4717     *
4718     * @param token The Binder token referencing the Activity we want to finish.
4719     * @param resultCode Result code, if any, from this Activity.
4720     * @param resultData Result data (Intent), if any, from this Activity.
4721     * @param finishTask Whether to finish the task associated with this Activity.
4722     *
4723     * @return Returns true if the activity successfully finished, or false if it is still running.
4724     */
4725    @Override
4726    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4727            int finishTask) {
4728        // Refuse possible leaked file descriptors
4729        if (resultData != null && resultData.hasFileDescriptors() == true) {
4730            throw new IllegalArgumentException("File descriptors passed in Intent");
4731        }
4732
4733        synchronized(this) {
4734            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4735            if (r == null) {
4736                return true;
4737            }
4738            // Keep track of the root activity of the task before we finish it
4739            TaskRecord tr = r.task;
4740            ActivityRecord rootR = tr.getRootActivity();
4741            if (rootR == null) {
4742                Slog.w(TAG, "Finishing task with all activities already finished");
4743            }
4744            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4745            // finish.
4746            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4747                    mStackSupervisor.isLastLockedTask(tr)) {
4748                Slog.i(TAG, "Not finishing task in lock task mode");
4749                mStackSupervisor.showLockTaskToast();
4750                return false;
4751            }
4752            if (mController != null) {
4753                // Find the first activity that is not finishing.
4754                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4755                if (next != null) {
4756                    // ask watcher if this is allowed
4757                    boolean resumeOK = true;
4758                    try {
4759                        resumeOK = mController.activityResuming(next.packageName);
4760                    } catch (RemoteException e) {
4761                        mController = null;
4762                        Watchdog.getInstance().setActivityController(null);
4763                    }
4764
4765                    if (!resumeOK) {
4766                        Slog.i(TAG, "Not finishing activity because controller resumed");
4767                        return false;
4768                    }
4769                }
4770            }
4771            final long origId = Binder.clearCallingIdentity();
4772            try {
4773                boolean res;
4774                final boolean finishWithRootActivity =
4775                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4776                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4777                        || (finishWithRootActivity && r == rootR)) {
4778                    // If requested, remove the task that is associated to this activity only if it
4779                    // was the root activity in the task. The result code and data is ignored
4780                    // because we don't support returning them across task boundaries. Also, to
4781                    // keep backwards compatibility we remove the task from recents when finishing
4782                    // task with root activity.
4783                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4784                    if (!res) {
4785                        Slog.i(TAG, "Removing task failed to finish activity");
4786                    }
4787                } else {
4788                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4789                            resultData, "app-request", true);
4790                    if (!res) {
4791                        Slog.i(TAG, "Failed to finish by app-request");
4792                    }
4793                }
4794                return res;
4795            } finally {
4796                Binder.restoreCallingIdentity(origId);
4797            }
4798        }
4799    }
4800
4801    @Override
4802    public final void finishHeavyWeightApp() {
4803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4804                != PackageManager.PERMISSION_GRANTED) {
4805            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4806                    + Binder.getCallingPid()
4807                    + ", uid=" + Binder.getCallingUid()
4808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4809            Slog.w(TAG, msg);
4810            throw new SecurityException(msg);
4811        }
4812
4813        synchronized(this) {
4814            if (mHeavyWeightProcess == null) {
4815                return;
4816            }
4817
4818            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4819            for (int i = 0; i < activities.size(); i++) {
4820                ActivityRecord r = activities.get(i);
4821                if (!r.finishing && r.isInStackLocked()) {
4822                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4823                            null, "finish-heavy", true);
4824                }
4825            }
4826
4827            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4828                    mHeavyWeightProcess.userId, 0));
4829            mHeavyWeightProcess = null;
4830        }
4831    }
4832
4833    @Override
4834    public void crashApplication(int uid, int initialPid, String packageName,
4835            String message) {
4836        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4837                != PackageManager.PERMISSION_GRANTED) {
4838            String msg = "Permission Denial: crashApplication() from pid="
4839                    + Binder.getCallingPid()
4840                    + ", uid=" + Binder.getCallingUid()
4841                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4842            Slog.w(TAG, msg);
4843            throw new SecurityException(msg);
4844        }
4845
4846        synchronized(this) {
4847            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4848        }
4849    }
4850
4851    @Override
4852    public final void finishSubActivity(IBinder token, String resultWho,
4853            int requestCode) {
4854        synchronized(this) {
4855            final long origId = Binder.clearCallingIdentity();
4856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4857            if (r != null) {
4858                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4859            }
4860            Binder.restoreCallingIdentity(origId);
4861        }
4862    }
4863
4864    @Override
4865    public boolean finishActivityAffinity(IBinder token) {
4866        synchronized(this) {
4867            final long origId = Binder.clearCallingIdentity();
4868            try {
4869                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4870                if (r == null) {
4871                    return false;
4872                }
4873
4874                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4875                // can finish.
4876                final TaskRecord task = r.task;
4877                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4878                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4879                    mStackSupervisor.showLockTaskToast();
4880                    return false;
4881                }
4882                return task.stack.finishActivityAffinityLocked(r);
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public void finishVoiceTask(IVoiceInteractionSession session) {
4891        synchronized (this) {
4892            final long origId = Binder.clearCallingIdentity();
4893            try {
4894                // TODO: VI Consider treating local voice interactions and voice tasks
4895                // differently here
4896                mStackSupervisor.finishVoiceTask(session);
4897            } finally {
4898                Binder.restoreCallingIdentity(origId);
4899            }
4900        }
4901
4902    }
4903
4904    @Override
4905    public boolean releaseActivityInstance(IBinder token) {
4906        synchronized(this) {
4907            final long origId = Binder.clearCallingIdentity();
4908            try {
4909                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4910                if (r == null) {
4911                    return false;
4912                }
4913                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4914            } finally {
4915                Binder.restoreCallingIdentity(origId);
4916            }
4917        }
4918    }
4919
4920    @Override
4921    public void releaseSomeActivities(IApplicationThread appInt) {
4922        synchronized(this) {
4923            final long origId = Binder.clearCallingIdentity();
4924            try {
4925                ProcessRecord app = getRecordForAppLocked(appInt);
4926                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4927            } finally {
4928                Binder.restoreCallingIdentity(origId);
4929            }
4930        }
4931    }
4932
4933    @Override
4934    public boolean willActivityBeVisible(IBinder token) {
4935        synchronized(this) {
4936            ActivityStack stack = ActivityRecord.getStackLocked(token);
4937            if (stack != null) {
4938                return stack.willActivityBeVisibleLocked(token);
4939            }
4940            return false;
4941        }
4942    }
4943
4944    @Override
4945    public void overridePendingTransition(IBinder token, String packageName,
4946            int enterAnim, int exitAnim) {
4947        synchronized(this) {
4948            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4949            if (self == null) {
4950                return;
4951            }
4952
4953            final long origId = Binder.clearCallingIdentity();
4954
4955            if (self.state == ActivityState.RESUMED
4956                    || self.state == ActivityState.PAUSING) {
4957                mWindowManager.overridePendingAppTransition(packageName,
4958                        enterAnim, exitAnim, null);
4959            }
4960
4961            Binder.restoreCallingIdentity(origId);
4962        }
4963    }
4964
4965    /**
4966     * Main function for removing an existing process from the activity manager
4967     * as a result of that process going away.  Clears out all connections
4968     * to the process.
4969     */
4970    private final void handleAppDiedLocked(ProcessRecord app,
4971            boolean restarting, boolean allowRestart) {
4972        int pid = app.pid;
4973        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4974        if (!kept && !restarting) {
4975            removeLruProcessLocked(app);
4976            if (pid > 0) {
4977                ProcessList.remove(pid);
4978            }
4979        }
4980
4981        if (mProfileProc == app) {
4982            clearProfilerLocked();
4983        }
4984
4985        // Remove this application's activities from active lists.
4986        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4987
4988        app.activities.clear();
4989
4990        if (app.instrumentationClass != null) {
4991            Slog.w(TAG, "Crash of app " + app.processName
4992                  + " running instrumentation " + app.instrumentationClass);
4993            Bundle info = new Bundle();
4994            info.putString("shortMsg", "Process crashed.");
4995            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4996        }
4997
4998        if (!restarting && hasVisibleActivities
4999                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5000            // If there was nothing to resume, and we are not already restarting this process, but
5001            // there is a visible activity that is hosted by the process...  then make sure all
5002            // visible activities are running, taking care of restarting this process.
5003            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5004        }
5005    }
5006
5007    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5008        IBinder threadBinder = thread.asBinder();
5009        // Find the application record.
5010        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5011            ProcessRecord rec = mLruProcesses.get(i);
5012            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5013                return i;
5014            }
5015        }
5016        return -1;
5017    }
5018
5019    final ProcessRecord getRecordForAppLocked(
5020            IApplicationThread thread) {
5021        if (thread == null) {
5022            return null;
5023        }
5024
5025        int appIndex = getLRURecordIndexForAppLocked(thread);
5026        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5027    }
5028
5029    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5030        // If there are no longer any background processes running,
5031        // and the app that died was not running instrumentation,
5032        // then tell everyone we are now low on memory.
5033        boolean haveBg = false;
5034        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5035            ProcessRecord rec = mLruProcesses.get(i);
5036            if (rec.thread != null
5037                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5038                haveBg = true;
5039                break;
5040            }
5041        }
5042
5043        if (!haveBg) {
5044            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5045            if (doReport) {
5046                long now = SystemClock.uptimeMillis();
5047                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5048                    doReport = false;
5049                } else {
5050                    mLastMemUsageReportTime = now;
5051                }
5052            }
5053            final ArrayList<ProcessMemInfo> memInfos
5054                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5055            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5056            long now = SystemClock.uptimeMillis();
5057            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5058                ProcessRecord rec = mLruProcesses.get(i);
5059                if (rec == dyingProc || rec.thread == null) {
5060                    continue;
5061                }
5062                if (doReport) {
5063                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5064                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5065                }
5066                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5067                    // The low memory report is overriding any current
5068                    // state for a GC request.  Make sure to do
5069                    // heavy/important/visible/foreground processes first.
5070                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5071                        rec.lastRequestedGc = 0;
5072                    } else {
5073                        rec.lastRequestedGc = rec.lastLowMemory;
5074                    }
5075                    rec.reportLowMemory = true;
5076                    rec.lastLowMemory = now;
5077                    mProcessesToGc.remove(rec);
5078                    addProcessToGcListLocked(rec);
5079                }
5080            }
5081            if (doReport) {
5082                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5083                mHandler.sendMessage(msg);
5084            }
5085            scheduleAppGcsLocked();
5086        }
5087    }
5088
5089    final void appDiedLocked(ProcessRecord app) {
5090       appDiedLocked(app, app.pid, app.thread, false);
5091    }
5092
5093    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5094            boolean fromBinderDied) {
5095        // First check if this ProcessRecord is actually active for the pid.
5096        synchronized (mPidsSelfLocked) {
5097            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5098            if (curProc != app) {
5099                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5100                return;
5101            }
5102        }
5103
5104        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5105        synchronized (stats) {
5106            stats.noteProcessDiedLocked(app.info.uid, pid);
5107        }
5108
5109        if (!app.killed) {
5110            if (!fromBinderDied) {
5111                Process.killProcessQuiet(pid);
5112            }
5113            killProcessGroup(app.uid, pid);
5114            app.killed = true;
5115        }
5116
5117        // Clean up already done if the process has been re-started.
5118        if (app.pid == pid && app.thread != null &&
5119                app.thread.asBinder() == thread.asBinder()) {
5120            boolean doLowMem = app.instrumentationClass == null;
5121            boolean doOomAdj = doLowMem;
5122            if (!app.killedByAm) {
5123                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5124                        + ") has died");
5125                mAllowLowerMemLevel = true;
5126            } else {
5127                // Note that we always want to do oom adj to update our state with the
5128                // new number of procs.
5129                mAllowLowerMemLevel = false;
5130                doLowMem = false;
5131            }
5132            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5133            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5134                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5135            handleAppDiedLocked(app, false, true);
5136
5137            if (doOomAdj) {
5138                updateOomAdjLocked();
5139            }
5140            if (doLowMem) {
5141                doLowMemReportIfNeededLocked(app);
5142            }
5143        } else if (app.pid != pid) {
5144            // A new process has already been started.
5145            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5146                    + ") has died and restarted (pid " + app.pid + ").");
5147            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5148        } else if (DEBUG_PROCESSES) {
5149            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5150                    + thread.asBinder());
5151        }
5152    }
5153
5154    /**
5155     * If a stack trace dump file is configured, dump process stack traces.
5156     * @param clearTraces causes the dump file to be erased prior to the new
5157     *    traces being written, if true; when false, the new traces will be
5158     *    appended to any existing file content.
5159     * @param firstPids of dalvik VM processes to dump stack traces for first
5160     * @param lastPids of dalvik VM processes to dump stack traces for last
5161     * @param nativeProcs optional list of native process names to dump stack crawls
5162     * @return file containing stack traces, or null if no dump file is configured
5163     */
5164    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5165            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5166        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5167        if (tracesPath == null || tracesPath.length() == 0) {
5168            return null;
5169        }
5170
5171        File tracesFile = new File(tracesPath);
5172        try {
5173            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5174            tracesFile.createNewFile();
5175            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5176        } catch (IOException e) {
5177            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5178            return null;
5179        }
5180
5181        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5182        return tracesFile;
5183    }
5184
5185    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5186            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5187        // Use a FileObserver to detect when traces finish writing.
5188        // The order of traces is considered important to maintain for legibility.
5189        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5190            @Override
5191            public synchronized void onEvent(int event, String path) { notify(); }
5192        };
5193
5194        try {
5195            observer.startWatching();
5196
5197            // First collect all of the stacks of the most important pids.
5198            if (firstPids != null) {
5199                try {
5200                    int num = firstPids.size();
5201                    for (int i = 0; i < num; i++) {
5202                        synchronized (observer) {
5203                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5204                                    + firstPids.get(i));
5205                            final long sime = SystemClock.elapsedRealtime();
5206                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5207                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5208                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5209                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5210                        }
5211                    }
5212                } catch (InterruptedException e) {
5213                    Slog.wtf(TAG, e);
5214                }
5215            }
5216
5217            // Next collect the stacks of the native pids
5218            if (nativeProcs != null) {
5219                int[] pids = Process.getPidsForCommands(nativeProcs);
5220                if (pids != null) {
5221                    for (int pid : pids) {
5222                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5223                        final long sime = SystemClock.elapsedRealtime();
5224                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5225                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5226                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5227                    }
5228                }
5229            }
5230
5231            // Lastly, measure CPU usage.
5232            if (processCpuTracker != null) {
5233                processCpuTracker.init();
5234                System.gc();
5235                processCpuTracker.update();
5236                try {
5237                    synchronized (processCpuTracker) {
5238                        processCpuTracker.wait(500); // measure over 1/2 second.
5239                    }
5240                } catch (InterruptedException e) {
5241                }
5242                processCpuTracker.update();
5243
5244                // We'll take the stack crawls of just the top apps using CPU.
5245                final int N = processCpuTracker.countWorkingStats();
5246                int numProcs = 0;
5247                for (int i=0; i<N && numProcs<5; i++) {
5248                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5249                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5250                        numProcs++;
5251                        try {
5252                            synchronized (observer) {
5253                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5254                                        + stats.pid);
5255                                final long stime = SystemClock.elapsedRealtime();
5256                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5257                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5258                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5259                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5260                            }
5261                        } catch (InterruptedException e) {
5262                            Slog.wtf(TAG, e);
5263                        }
5264                    } else if (DEBUG_ANR) {
5265                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5266                                + stats.pid);
5267                    }
5268                }
5269            }
5270        } finally {
5271            observer.stopWatching();
5272        }
5273    }
5274
5275    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5276        if (true || IS_USER_BUILD) {
5277            return;
5278        }
5279        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5280        if (tracesPath == null || tracesPath.length() == 0) {
5281            return;
5282        }
5283
5284        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5285        StrictMode.allowThreadDiskWrites();
5286        try {
5287            final File tracesFile = new File(tracesPath);
5288            final File tracesDir = tracesFile.getParentFile();
5289            final File tracesTmp = new File(tracesDir, "__tmp__");
5290            try {
5291                if (tracesFile.exists()) {
5292                    tracesTmp.delete();
5293                    tracesFile.renameTo(tracesTmp);
5294                }
5295                StringBuilder sb = new StringBuilder();
5296                Time tobj = new Time();
5297                tobj.set(System.currentTimeMillis());
5298                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5299                sb.append(": ");
5300                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5301                sb.append(" since ");
5302                sb.append(msg);
5303                FileOutputStream fos = new FileOutputStream(tracesFile);
5304                fos.write(sb.toString().getBytes());
5305                if (app == null) {
5306                    fos.write("\n*** No application process!".getBytes());
5307                }
5308                fos.close();
5309                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5310            } catch (IOException e) {
5311                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5312                return;
5313            }
5314
5315            if (app != null) {
5316                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5317                firstPids.add(app.pid);
5318                dumpStackTraces(tracesPath, firstPids, null, null, null);
5319            }
5320
5321            File lastTracesFile = null;
5322            File curTracesFile = null;
5323            for (int i=9; i>=0; i--) {
5324                String name = String.format(Locale.US, "slow%02d.txt", i);
5325                curTracesFile = new File(tracesDir, name);
5326                if (curTracesFile.exists()) {
5327                    if (lastTracesFile != null) {
5328                        curTracesFile.renameTo(lastTracesFile);
5329                    } else {
5330                        curTracesFile.delete();
5331                    }
5332                }
5333                lastTracesFile = curTracesFile;
5334            }
5335            tracesFile.renameTo(curTracesFile);
5336            if (tracesTmp.exists()) {
5337                tracesTmp.renameTo(tracesFile);
5338            }
5339        } finally {
5340            StrictMode.setThreadPolicy(oldPolicy);
5341        }
5342    }
5343
5344    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5345        if (!mLaunchWarningShown) {
5346            mLaunchWarningShown = true;
5347            mUiHandler.post(new Runnable() {
5348                @Override
5349                public void run() {
5350                    synchronized (ActivityManagerService.this) {
5351                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5352                        d.show();
5353                        mUiHandler.postDelayed(new Runnable() {
5354                            @Override
5355                            public void run() {
5356                                synchronized (ActivityManagerService.this) {
5357                                    d.dismiss();
5358                                    mLaunchWarningShown = false;
5359                                }
5360                            }
5361                        }, 4000);
5362                    }
5363                }
5364            });
5365        }
5366    }
5367
5368    @Override
5369    public boolean clearApplicationUserData(final String packageName,
5370            final IPackageDataObserver observer, int userId) {
5371        enforceNotIsolatedCaller("clearApplicationUserData");
5372        int uid = Binder.getCallingUid();
5373        int pid = Binder.getCallingPid();
5374        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5375                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5376
5377        final DevicePolicyManagerInternal dpmi = LocalServices
5378                .getService(DevicePolicyManagerInternal.class);
5379        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5380            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5381        }
5382
5383        long callingId = Binder.clearCallingIdentity();
5384        try {
5385            IPackageManager pm = AppGlobals.getPackageManager();
5386            int pkgUid = -1;
5387            synchronized(this) {
5388                try {
5389                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5390                } catch (RemoteException e) {
5391                }
5392                if (pkgUid == -1) {
5393                    Slog.w(TAG, "Invalid packageName: " + packageName);
5394                    if (observer != null) {
5395                        try {
5396                            observer.onRemoveCompleted(packageName, false);
5397                        } catch (RemoteException e) {
5398                            Slog.i(TAG, "Observer no longer exists.");
5399                        }
5400                    }
5401                    return false;
5402                }
5403                if (uid == pkgUid || checkComponentPermission(
5404                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5405                        pid, uid, -1, true)
5406                        == PackageManager.PERMISSION_GRANTED) {
5407                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5408                } else {
5409                    throw new SecurityException("PID " + pid + " does not have permission "
5410                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5411                                    + " of package " + packageName);
5412                }
5413
5414                // Remove all tasks match the cleared application package and user
5415                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5416                    final TaskRecord tr = mRecentTasks.get(i);
5417                    final String taskPackageName =
5418                            tr.getBaseIntent().getComponent().getPackageName();
5419                    if (tr.userId != userId) continue;
5420                    if (!taskPackageName.equals(packageName)) continue;
5421                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5422                }
5423            }
5424
5425            final int pkgUidF = pkgUid;
5426            final int userIdF = userId;
5427            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5428                @Override
5429                public void onRemoveCompleted(String packageName, boolean succeeded)
5430                        throws RemoteException {
5431                    synchronized (ActivityManagerService.this) {
5432                        finishForceStopPackageLocked(packageName, pkgUidF);
5433                    }
5434
5435                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5436                            Uri.fromParts("package", packageName, null));
5437                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5438                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5439                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5440                            null, null, 0, null, null, null, null, false, false, userIdF);
5441
5442                    if (observer != null) {
5443                        observer.onRemoveCompleted(packageName, succeeded);
5444                    }
5445                }
5446            };
5447
5448            try {
5449                // Clear application user data
5450                pm.clearApplicationUserData(packageName, localObserver, userId);
5451
5452                synchronized(this) {
5453                    // Remove all permissions granted from/to this package
5454                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5455                }
5456
5457                // Remove all zen rules created by this package; revoke it's zen access.
5458                INotificationManager inm = NotificationManager.getService();
5459                inm.removeAutomaticZenRules(packageName);
5460                inm.setNotificationPolicyAccessGranted(packageName, false);
5461
5462            } catch (RemoteException e) {
5463            }
5464        } finally {
5465            Binder.restoreCallingIdentity(callingId);
5466        }
5467        return true;
5468    }
5469
5470    @Override
5471    public void killBackgroundProcesses(final String packageName, int userId) {
5472        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5473                != PackageManager.PERMISSION_GRANTED &&
5474                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5475                        != PackageManager.PERMISSION_GRANTED) {
5476            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5477                    + Binder.getCallingPid()
5478                    + ", uid=" + Binder.getCallingUid()
5479                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5480            Slog.w(TAG, msg);
5481            throw new SecurityException(msg);
5482        }
5483
5484        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5485                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5486        long callingId = Binder.clearCallingIdentity();
5487        try {
5488            IPackageManager pm = AppGlobals.getPackageManager();
5489            synchronized(this) {
5490                int appId = -1;
5491                try {
5492                    appId = UserHandle.getAppId(
5493                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5494                } catch (RemoteException e) {
5495                }
5496                if (appId == -1) {
5497                    Slog.w(TAG, "Invalid packageName: " + packageName);
5498                    return;
5499                }
5500                killPackageProcessesLocked(packageName, appId, userId,
5501                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5502            }
5503        } finally {
5504            Binder.restoreCallingIdentity(callingId);
5505        }
5506    }
5507
5508    @Override
5509    public void killAllBackgroundProcesses() {
5510        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5511                != PackageManager.PERMISSION_GRANTED) {
5512            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5513                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5514                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5515            Slog.w(TAG, msg);
5516            throw new SecurityException(msg);
5517        }
5518
5519        final long callingId = Binder.clearCallingIdentity();
5520        try {
5521            synchronized (this) {
5522                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5523                final int NP = mProcessNames.getMap().size();
5524                for (int ip = 0; ip < NP; ip++) {
5525                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5526                    final int NA = apps.size();
5527                    for (int ia = 0; ia < NA; ia++) {
5528                        final ProcessRecord app = apps.valueAt(ia);
5529                        if (app.persistent) {
5530                            // We don't kill persistent processes.
5531                            continue;
5532                        }
5533                        if (app.removed) {
5534                            procs.add(app);
5535                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5536                            app.removed = true;
5537                            procs.add(app);
5538                        }
5539                    }
5540                }
5541
5542                final int N = procs.size();
5543                for (int i = 0; i < N; i++) {
5544                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5545                }
5546
5547                mAllowLowerMemLevel = true;
5548
5549                updateOomAdjLocked();
5550                doLowMemReportIfNeededLocked(null);
5551            }
5552        } finally {
5553            Binder.restoreCallingIdentity(callingId);
5554        }
5555    }
5556
5557    /**
5558     * Kills all background processes, except those matching any of the
5559     * specified properties.
5560     *
5561     * @param minTargetSdk the target SDK version at or above which to preserve
5562     *                     processes, or {@code -1} to ignore the target SDK
5563     * @param maxProcState the process state at or below which to preserve
5564     *                     processes, or {@code -1} to ignore the process state
5565     */
5566    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5567        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5568                != PackageManager.PERMISSION_GRANTED) {
5569            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5570                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5571                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5572            Slog.w(TAG, msg);
5573            throw new SecurityException(msg);
5574        }
5575
5576        final long callingId = Binder.clearCallingIdentity();
5577        try {
5578            synchronized (this) {
5579                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5580                final int NP = mProcessNames.getMap().size();
5581                for (int ip = 0; ip < NP; ip++) {
5582                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5583                    final int NA = apps.size();
5584                    for (int ia = 0; ia < NA; ia++) {
5585                        final ProcessRecord app = apps.valueAt(ia);
5586                        if (app.removed) {
5587                            procs.add(app);
5588                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5589                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5590                            app.removed = true;
5591                            procs.add(app);
5592                        }
5593                    }
5594                }
5595
5596                final int N = procs.size();
5597                for (int i = 0; i < N; i++) {
5598                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5599                }
5600            }
5601        } finally {
5602            Binder.restoreCallingIdentity(callingId);
5603        }
5604    }
5605
5606    @Override
5607    public void forceStopPackage(final String packageName, int userId) {
5608        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5609                != PackageManager.PERMISSION_GRANTED) {
5610            String msg = "Permission Denial: forceStopPackage() from pid="
5611                    + Binder.getCallingPid()
5612                    + ", uid=" + Binder.getCallingUid()
5613                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5614            Slog.w(TAG, msg);
5615            throw new SecurityException(msg);
5616        }
5617        final int callingPid = Binder.getCallingPid();
5618        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5619                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5620        long callingId = Binder.clearCallingIdentity();
5621        try {
5622            IPackageManager pm = AppGlobals.getPackageManager();
5623            synchronized(this) {
5624                int[] users = userId == UserHandle.USER_ALL
5625                        ? mUserController.getUsers() : new int[] { userId };
5626                for (int user : users) {
5627                    int pkgUid = -1;
5628                    try {
5629                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5630                                user);
5631                    } catch (RemoteException e) {
5632                    }
5633                    if (pkgUid == -1) {
5634                        Slog.w(TAG, "Invalid packageName: " + packageName);
5635                        continue;
5636                    }
5637                    try {
5638                        pm.setPackageStoppedState(packageName, true, user);
5639                    } catch (RemoteException e) {
5640                    } catch (IllegalArgumentException e) {
5641                        Slog.w(TAG, "Failed trying to unstop package "
5642                                + packageName + ": " + e);
5643                    }
5644                    if (mUserController.isUserRunningLocked(user, 0)) {
5645                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5646                        finishForceStopPackageLocked(packageName, pkgUid);
5647                    }
5648                }
5649            }
5650        } finally {
5651            Binder.restoreCallingIdentity(callingId);
5652        }
5653    }
5654
5655    @Override
5656    public void addPackageDependency(String packageName) {
5657        synchronized (this) {
5658            int callingPid = Binder.getCallingPid();
5659            if (callingPid == Process.myPid()) {
5660                //  Yeah, um, no.
5661                return;
5662            }
5663            ProcessRecord proc;
5664            synchronized (mPidsSelfLocked) {
5665                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5666            }
5667            if (proc != null) {
5668                if (proc.pkgDeps == null) {
5669                    proc.pkgDeps = new ArraySet<String>(1);
5670                }
5671                proc.pkgDeps.add(packageName);
5672            }
5673        }
5674    }
5675
5676    /*
5677     * The pkg name and app id have to be specified.
5678     */
5679    @Override
5680    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5681        if (pkg == null) {
5682            return;
5683        }
5684        // Make sure the uid is valid.
5685        if (appid < 0) {
5686            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5687            return;
5688        }
5689        int callerUid = Binder.getCallingUid();
5690        // Only the system server can kill an application
5691        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5692            // Post an aysnc message to kill the application
5693            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5694            msg.arg1 = appid;
5695            msg.arg2 = 0;
5696            Bundle bundle = new Bundle();
5697            bundle.putString("pkg", pkg);
5698            bundle.putString("reason", reason);
5699            msg.obj = bundle;
5700            mHandler.sendMessage(msg);
5701        } else {
5702            throw new SecurityException(callerUid + " cannot kill pkg: " +
5703                    pkg);
5704        }
5705    }
5706
5707    @Override
5708    public void closeSystemDialogs(String reason) {
5709        enforceNotIsolatedCaller("closeSystemDialogs");
5710
5711        final int pid = Binder.getCallingPid();
5712        final int uid = Binder.getCallingUid();
5713        final long origId = Binder.clearCallingIdentity();
5714        try {
5715            synchronized (this) {
5716                // Only allow this from foreground processes, so that background
5717                // applications can't abuse it to prevent system UI from being shown.
5718                if (uid >= Process.FIRST_APPLICATION_UID) {
5719                    ProcessRecord proc;
5720                    synchronized (mPidsSelfLocked) {
5721                        proc = mPidsSelfLocked.get(pid);
5722                    }
5723                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5724                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5725                                + " from background process " + proc);
5726                        return;
5727                    }
5728                }
5729                closeSystemDialogsLocked(reason);
5730            }
5731        } finally {
5732            Binder.restoreCallingIdentity(origId);
5733        }
5734    }
5735
5736    void closeSystemDialogsLocked(String reason) {
5737        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5738        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5739                | Intent.FLAG_RECEIVER_FOREGROUND);
5740        if (reason != null) {
5741            intent.putExtra("reason", reason);
5742        }
5743        mWindowManager.closeSystemDialogs(reason);
5744
5745        mStackSupervisor.closeSystemDialogsLocked();
5746
5747        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5748                AppOpsManager.OP_NONE, null, false, false,
5749                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5750    }
5751
5752    @Override
5753    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5754        enforceNotIsolatedCaller("getProcessMemoryInfo");
5755        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5756        for (int i=pids.length-1; i>=0; i--) {
5757            ProcessRecord proc;
5758            int oomAdj;
5759            synchronized (this) {
5760                synchronized (mPidsSelfLocked) {
5761                    proc = mPidsSelfLocked.get(pids[i]);
5762                    oomAdj = proc != null ? proc.setAdj : 0;
5763                }
5764            }
5765            infos[i] = new Debug.MemoryInfo();
5766            Debug.getMemoryInfo(pids[i], infos[i]);
5767            if (proc != null) {
5768                synchronized (this) {
5769                    if (proc.thread != null && proc.setAdj == oomAdj) {
5770                        // Record this for posterity if the process has been stable.
5771                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5772                                infos[i].getTotalUss(), false, proc.pkgList);
5773                    }
5774                }
5775            }
5776        }
5777        return infos;
5778    }
5779
5780    @Override
5781    public long[] getProcessPss(int[] pids) {
5782        enforceNotIsolatedCaller("getProcessPss");
5783        long[] pss = new long[pids.length];
5784        for (int i=pids.length-1; i>=0; i--) {
5785            ProcessRecord proc;
5786            int oomAdj;
5787            synchronized (this) {
5788                synchronized (mPidsSelfLocked) {
5789                    proc = mPidsSelfLocked.get(pids[i]);
5790                    oomAdj = proc != null ? proc.setAdj : 0;
5791                }
5792            }
5793            long[] tmpUss = new long[1];
5794            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5795            if (proc != null) {
5796                synchronized (this) {
5797                    if (proc.thread != null && proc.setAdj == oomAdj) {
5798                        // Record this for posterity if the process has been stable.
5799                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5800                    }
5801                }
5802            }
5803        }
5804        return pss;
5805    }
5806
5807    @Override
5808    public void killApplicationProcess(String processName, int uid) {
5809        if (processName == null) {
5810            return;
5811        }
5812
5813        int callerUid = Binder.getCallingUid();
5814        // Only the system server can kill an application
5815        if (callerUid == Process.SYSTEM_UID) {
5816            synchronized (this) {
5817                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5818                if (app != null && app.thread != null) {
5819                    try {
5820                        app.thread.scheduleSuicide();
5821                    } catch (RemoteException e) {
5822                        // If the other end already died, then our work here is done.
5823                    }
5824                } else {
5825                    Slog.w(TAG, "Process/uid not found attempting kill of "
5826                            + processName + " / " + uid);
5827                }
5828            }
5829        } else {
5830            throw new SecurityException(callerUid + " cannot kill app process: " +
5831                    processName);
5832        }
5833    }
5834
5835    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5836        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5837                false, true, false, false, UserHandle.getUserId(uid), reason);
5838    }
5839
5840    private void finishForceStopPackageLocked(final String packageName, int uid) {
5841        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5842                Uri.fromParts("package", packageName, null));
5843        if (!mProcessesReady) {
5844            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5845                    | Intent.FLAG_RECEIVER_FOREGROUND);
5846        }
5847        intent.putExtra(Intent.EXTRA_UID, uid);
5848        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5849        broadcastIntentLocked(null, null, intent,
5850                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5851                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5852    }
5853
5854
5855    private final boolean killPackageProcessesLocked(String packageName, int appId,
5856            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5857            boolean doit, boolean evenPersistent, String reason) {
5858        ArrayList<ProcessRecord> procs = new ArrayList<>();
5859
5860        // Remove all processes this package may have touched: all with the
5861        // same UID (except for the system or root user), and all whose name
5862        // matches the package name.
5863        final int NP = mProcessNames.getMap().size();
5864        for (int ip=0; ip<NP; ip++) {
5865            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5866            final int NA = apps.size();
5867            for (int ia=0; ia<NA; ia++) {
5868                ProcessRecord app = apps.valueAt(ia);
5869                if (app.persistent && !evenPersistent) {
5870                    // we don't kill persistent processes
5871                    continue;
5872                }
5873                if (app.removed) {
5874                    if (doit) {
5875                        procs.add(app);
5876                    }
5877                    continue;
5878                }
5879
5880                // Skip process if it doesn't meet our oom adj requirement.
5881                if (app.setAdj < minOomAdj) {
5882                    continue;
5883                }
5884
5885                // If no package is specified, we call all processes under the
5886                // give user id.
5887                if (packageName == null) {
5888                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5889                        continue;
5890                    }
5891                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5892                        continue;
5893                    }
5894                // Package has been specified, we want to hit all processes
5895                // that match it.  We need to qualify this by the processes
5896                // that are running under the specified app and user ID.
5897                } else {
5898                    final boolean isDep = app.pkgDeps != null
5899                            && app.pkgDeps.contains(packageName);
5900                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5901                        continue;
5902                    }
5903                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5904                        continue;
5905                    }
5906                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5907                        continue;
5908                    }
5909                }
5910
5911                // Process has passed all conditions, kill it!
5912                if (!doit) {
5913                    return true;
5914                }
5915                app.removed = true;
5916                procs.add(app);
5917            }
5918        }
5919
5920        int N = procs.size();
5921        for (int i=0; i<N; i++) {
5922            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5923        }
5924        updateOomAdjLocked();
5925        return N > 0;
5926    }
5927
5928    private void cleanupDisabledPackageComponentsLocked(
5929            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5930
5931        Set<String> disabledClasses = null;
5932        boolean packageDisabled = false;
5933        IPackageManager pm = AppGlobals.getPackageManager();
5934
5935        if (changedClasses == null) {
5936            // Nothing changed...
5937            return;
5938        }
5939
5940        // Determine enable/disable state of the package and its components.
5941        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5942        for (int i = changedClasses.length - 1; i >= 0; i--) {
5943            final String changedClass = changedClasses[i];
5944
5945            if (changedClass.equals(packageName)) {
5946                try {
5947                    // Entire package setting changed
5948                    enabled = pm.getApplicationEnabledSetting(packageName,
5949                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5950                } catch (Exception e) {
5951                    // No such package/component; probably racing with uninstall.  In any
5952                    // event it means we have nothing further to do here.
5953                    return;
5954                }
5955                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5956                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5957                if (packageDisabled) {
5958                    // Entire package is disabled.
5959                    // No need to continue to check component states.
5960                    disabledClasses = null;
5961                    break;
5962                }
5963            } else {
5964                try {
5965                    enabled = pm.getComponentEnabledSetting(
5966                            new ComponentName(packageName, changedClass),
5967                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5968                } catch (Exception e) {
5969                    // As above, probably racing with uninstall.
5970                    return;
5971                }
5972                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5973                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5974                    if (disabledClasses == null) {
5975                        disabledClasses = new ArraySet<>(changedClasses.length);
5976                    }
5977                    disabledClasses.add(changedClass);
5978                }
5979            }
5980        }
5981
5982        if (!packageDisabled && disabledClasses == null) {
5983            // Nothing to do here...
5984            return;
5985        }
5986
5987        // Clean-up disabled activities.
5988        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5989                packageName, disabledClasses, true, false, userId) && mBooted) {
5990            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5991            mStackSupervisor.scheduleIdleLocked();
5992        }
5993
5994        // Clean-up disabled tasks
5995        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5996
5997        // Clean-up disabled services.
5998        mServices.bringDownDisabledPackageServicesLocked(
5999                packageName, disabledClasses, userId, false, killProcess, true);
6000
6001        // Clean-up disabled providers.
6002        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6003        mProviderMap.collectPackageProvidersLocked(
6004                packageName, disabledClasses, true, false, userId, providers);
6005        for (int i = providers.size() - 1; i >= 0; i--) {
6006            removeDyingProviderLocked(null, providers.get(i), true);
6007        }
6008
6009        // Clean-up disabled broadcast receivers.
6010        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6011            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6012                    packageName, disabledClasses, userId, true);
6013        }
6014
6015    }
6016
6017    final boolean clearBroadcastQueueForUserLocked(int userId) {
6018        boolean didSomething = false;
6019        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6020            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6021                    null, null, userId, true);
6022        }
6023        return didSomething;
6024    }
6025
6026    final boolean forceStopPackageLocked(String packageName, int appId,
6027            boolean callerWillRestart, boolean purgeCache, boolean doit,
6028            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6029        int i;
6030
6031        if (userId == UserHandle.USER_ALL && packageName == null) {
6032            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6033        }
6034
6035        if (appId < 0 && packageName != null) {
6036            try {
6037                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6038                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6039            } catch (RemoteException e) {
6040            }
6041        }
6042
6043        if (doit) {
6044            if (packageName != null) {
6045                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6046                        + " user=" + userId + ": " + reason);
6047            } else {
6048                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6049            }
6050
6051            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6052        }
6053
6054        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6055                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6056                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6057
6058        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6059                packageName, null, doit, evenPersistent, userId)) {
6060            if (!doit) {
6061                return true;
6062            }
6063            didSomething = true;
6064        }
6065
6066        if (mServices.bringDownDisabledPackageServicesLocked(
6067                packageName, null, userId, evenPersistent, true, doit)) {
6068            if (!doit) {
6069                return true;
6070            }
6071            didSomething = true;
6072        }
6073
6074        if (packageName == null) {
6075            // Remove all sticky broadcasts from this user.
6076            mStickyBroadcasts.remove(userId);
6077        }
6078
6079        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6080        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6081                userId, providers)) {
6082            if (!doit) {
6083                return true;
6084            }
6085            didSomething = true;
6086        }
6087        for (i = providers.size() - 1; i >= 0; i--) {
6088            removeDyingProviderLocked(null, providers.get(i), true);
6089        }
6090
6091        // Remove transient permissions granted from/to this package/user
6092        removeUriPermissionsForPackageLocked(packageName, userId, false);
6093
6094        if (doit) {
6095            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6096                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6097                        packageName, null, userId, doit);
6098            }
6099        }
6100
6101        if (packageName == null || uninstalling) {
6102            // Remove pending intents.  For now we only do this when force
6103            // stopping users, because we have some problems when doing this
6104            // for packages -- app widgets are not currently cleaned up for
6105            // such packages, so they can be left with bad pending intents.
6106            if (mIntentSenderRecords.size() > 0) {
6107                Iterator<WeakReference<PendingIntentRecord>> it
6108                        = mIntentSenderRecords.values().iterator();
6109                while (it.hasNext()) {
6110                    WeakReference<PendingIntentRecord> wpir = it.next();
6111                    if (wpir == null) {
6112                        it.remove();
6113                        continue;
6114                    }
6115                    PendingIntentRecord pir = wpir.get();
6116                    if (pir == null) {
6117                        it.remove();
6118                        continue;
6119                    }
6120                    if (packageName == null) {
6121                        // Stopping user, remove all objects for the user.
6122                        if (pir.key.userId != userId) {
6123                            // Not the same user, skip it.
6124                            continue;
6125                        }
6126                    } else {
6127                        if (UserHandle.getAppId(pir.uid) != appId) {
6128                            // Different app id, skip it.
6129                            continue;
6130                        }
6131                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6132                            // Different user, skip it.
6133                            continue;
6134                        }
6135                        if (!pir.key.packageName.equals(packageName)) {
6136                            // Different package, skip it.
6137                            continue;
6138                        }
6139                    }
6140                    if (!doit) {
6141                        return true;
6142                    }
6143                    didSomething = true;
6144                    it.remove();
6145                    pir.canceled = true;
6146                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6147                        pir.key.activity.pendingResults.remove(pir.ref);
6148                    }
6149                }
6150            }
6151        }
6152
6153        if (doit) {
6154            if (purgeCache && packageName != null) {
6155                AttributeCache ac = AttributeCache.instance();
6156                if (ac != null) {
6157                    ac.removePackage(packageName);
6158                }
6159            }
6160            if (mBooted) {
6161                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6162                mStackSupervisor.scheduleIdleLocked();
6163            }
6164        }
6165
6166        return didSomething;
6167    }
6168
6169    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6170        ProcessRecord old = mProcessNames.remove(name, uid);
6171        if (old != null) {
6172            old.uidRecord.numProcs--;
6173            if (old.uidRecord.numProcs == 0) {
6174                // No more processes using this uid, tell clients it is gone.
6175                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6176                        "No more processes in " + old.uidRecord);
6177                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6178                mActiveUids.remove(uid);
6179                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6180            }
6181            old.uidRecord = null;
6182        }
6183        mIsolatedProcesses.remove(uid);
6184        return old;
6185    }
6186
6187    private final void addProcessNameLocked(ProcessRecord proc) {
6188        // We shouldn't already have a process under this name, but just in case we
6189        // need to clean up whatever may be there now.
6190        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6191        if (old == proc && proc.persistent) {
6192            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6193            Slog.w(TAG, "Re-adding persistent process " + proc);
6194        } else if (old != null) {
6195            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6196        }
6197        UidRecord uidRec = mActiveUids.get(proc.uid);
6198        if (uidRec == null) {
6199            uidRec = new UidRecord(proc.uid);
6200            // This is the first appearance of the uid, report it now!
6201            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6202                    "Creating new process uid: " + uidRec);
6203            mActiveUids.put(proc.uid, uidRec);
6204            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6205            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6206        }
6207        proc.uidRecord = uidRec;
6208        uidRec.numProcs++;
6209        mProcessNames.put(proc.processName, proc.uid, proc);
6210        if (proc.isolated) {
6211            mIsolatedProcesses.put(proc.uid, proc);
6212        }
6213    }
6214
6215    boolean removeProcessLocked(ProcessRecord app,
6216            boolean callerWillRestart, boolean allowRestart, String reason) {
6217        final String name = app.processName;
6218        final int uid = app.uid;
6219        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6220            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6221
6222        ProcessRecord old = mProcessNames.get(name, uid);
6223        if (old != app) {
6224            // This process is no longer active, so nothing to do.
6225            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6226            return false;
6227        }
6228        removeProcessNameLocked(name, uid);
6229        if (mHeavyWeightProcess == app) {
6230            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6231                    mHeavyWeightProcess.userId, 0));
6232            mHeavyWeightProcess = null;
6233        }
6234        boolean needRestart = false;
6235        if (app.pid > 0 && app.pid != MY_PID) {
6236            int pid = app.pid;
6237            synchronized (mPidsSelfLocked) {
6238                mPidsSelfLocked.remove(pid);
6239                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6240            }
6241            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6242            if (app.isolated) {
6243                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6244            }
6245            boolean willRestart = false;
6246            if (app.persistent && !app.isolated) {
6247                if (!callerWillRestart) {
6248                    willRestart = true;
6249                } else {
6250                    needRestart = true;
6251                }
6252            }
6253            app.kill(reason, true);
6254            handleAppDiedLocked(app, willRestart, allowRestart);
6255            if (willRestart) {
6256                removeLruProcessLocked(app);
6257                addAppLocked(app.info, false, null /* ABI override */);
6258            }
6259        } else {
6260            mRemovedProcesses.add(app);
6261        }
6262
6263        return needRestart;
6264    }
6265
6266    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6267        cleanupAppInLaunchingProvidersLocked(app, true);
6268        removeProcessLocked(app, false, true, "timeout publishing content providers");
6269    }
6270
6271    private final void processStartTimedOutLocked(ProcessRecord app) {
6272        final int pid = app.pid;
6273        boolean gone = false;
6274        synchronized (mPidsSelfLocked) {
6275            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6276            if (knownApp != null && knownApp.thread == null) {
6277                mPidsSelfLocked.remove(pid);
6278                gone = true;
6279            }
6280        }
6281
6282        if (gone) {
6283            Slog.w(TAG, "Process " + app + " failed to attach");
6284            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6285                    pid, app.uid, app.processName);
6286            removeProcessNameLocked(app.processName, app.uid);
6287            if (mHeavyWeightProcess == app) {
6288                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6289                        mHeavyWeightProcess.userId, 0));
6290                mHeavyWeightProcess = null;
6291            }
6292            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6293            if (app.isolated) {
6294                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6295            }
6296            // Take care of any launching providers waiting for this process.
6297            cleanupAppInLaunchingProvidersLocked(app, true);
6298            // Take care of any services that are waiting for the process.
6299            mServices.processStartTimedOutLocked(app);
6300            app.kill("start timeout", true);
6301            removeLruProcessLocked(app);
6302            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6303                Slog.w(TAG, "Unattached app died before backup, skipping");
6304                try {
6305                    IBackupManager bm = IBackupManager.Stub.asInterface(
6306                            ServiceManager.getService(Context.BACKUP_SERVICE));
6307                    bm.agentDisconnected(app.info.packageName);
6308                } catch (RemoteException e) {
6309                    // Can't happen; the backup manager is local
6310                }
6311            }
6312            if (isPendingBroadcastProcessLocked(pid)) {
6313                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6314                skipPendingBroadcastLocked(pid);
6315            }
6316        } else {
6317            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6318        }
6319    }
6320
6321    private final boolean attachApplicationLocked(IApplicationThread thread,
6322            int pid) {
6323
6324        // Find the application record that is being attached...  either via
6325        // the pid if we are running in multiple processes, or just pull the
6326        // next app record if we are emulating process with anonymous threads.
6327        ProcessRecord app;
6328        if (pid != MY_PID && pid >= 0) {
6329            synchronized (mPidsSelfLocked) {
6330                app = mPidsSelfLocked.get(pid);
6331            }
6332        } else {
6333            app = null;
6334        }
6335
6336        if (app == null) {
6337            Slog.w(TAG, "No pending application record for pid " + pid
6338                    + " (IApplicationThread " + thread + "); dropping process");
6339            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6340            if (pid > 0 && pid != MY_PID) {
6341                Process.killProcessQuiet(pid);
6342                //TODO: killProcessGroup(app.info.uid, pid);
6343            } else {
6344                try {
6345                    thread.scheduleExit();
6346                } catch (Exception e) {
6347                    // Ignore exceptions.
6348                }
6349            }
6350            return false;
6351        }
6352
6353        // If this application record is still attached to a previous
6354        // process, clean it up now.
6355        if (app.thread != null) {
6356            handleAppDiedLocked(app, true, true);
6357        }
6358
6359        // Tell the process all about itself.
6360
6361        if (DEBUG_ALL) Slog.v(
6362                TAG, "Binding process pid " + pid + " to record " + app);
6363
6364        final String processName = app.processName;
6365        try {
6366            AppDeathRecipient adr = new AppDeathRecipient(
6367                    app, pid, thread);
6368            thread.asBinder().linkToDeath(adr, 0);
6369            app.deathRecipient = adr;
6370        } catch (RemoteException e) {
6371            app.resetPackageList(mProcessStats);
6372            startProcessLocked(app, "link fail", processName);
6373            return false;
6374        }
6375
6376        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6377
6378        app.makeActive(thread, mProcessStats);
6379        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6380        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6381        app.forcingToForeground = null;
6382        updateProcessForegroundLocked(app, false, false);
6383        app.hasShownUi = false;
6384        app.debugging = false;
6385        app.cached = false;
6386        app.killedByAm = false;
6387
6388        // We carefully use the same state that PackageManager uses for
6389        // filtering, since we use this flag to decide if we need to install
6390        // providers when user is unlocked later
6391        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6392
6393        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6394
6395        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6396        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6397
6398        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6399            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6400            msg.obj = app;
6401            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6402        }
6403
6404        if (!normalMode) {
6405            Slog.i(TAG, "Launching preboot mode app: " + app);
6406        }
6407
6408        if (DEBUG_ALL) Slog.v(
6409            TAG, "New app record " + app
6410            + " thread=" + thread.asBinder() + " pid=" + pid);
6411        try {
6412            int testMode = IApplicationThread.DEBUG_OFF;
6413            if (mDebugApp != null && mDebugApp.equals(processName)) {
6414                testMode = mWaitForDebugger
6415                    ? IApplicationThread.DEBUG_WAIT
6416                    : IApplicationThread.DEBUG_ON;
6417                app.debugging = true;
6418                if (mDebugTransient) {
6419                    mDebugApp = mOrigDebugApp;
6420                    mWaitForDebugger = mOrigWaitForDebugger;
6421                }
6422            }
6423            String profileFile = app.instrumentationProfileFile;
6424            ParcelFileDescriptor profileFd = null;
6425            int samplingInterval = 0;
6426            boolean profileAutoStop = false;
6427            if (mProfileApp != null && mProfileApp.equals(processName)) {
6428                mProfileProc = app;
6429                profileFile = mProfileFile;
6430                profileFd = mProfileFd;
6431                samplingInterval = mSamplingInterval;
6432                profileAutoStop = mAutoStopProfiler;
6433            }
6434            boolean enableTrackAllocation = false;
6435            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6436                enableTrackAllocation = true;
6437                mTrackAllocationApp = null;
6438            }
6439
6440            // If the app is being launched for restore or full backup, set it up specially
6441            boolean isRestrictedBackupMode = false;
6442            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6443                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6444                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6445                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6446                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6447            }
6448
6449            if (app.instrumentationClass != null) {
6450                notifyPackageUse(app.instrumentationClass.getPackageName(),
6451                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6452            }
6453            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6454                    + processName + " with config " + mConfiguration);
6455            ApplicationInfo appInfo = app.instrumentationInfo != null
6456                    ? app.instrumentationInfo : app.info;
6457            app.compat = compatibilityInfoForPackageLocked(appInfo);
6458            if (profileFd != null) {
6459                profileFd = profileFd.dup();
6460            }
6461            ProfilerInfo profilerInfo = profileFile == null ? null
6462                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6463            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6464                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6465                    app.instrumentationUiAutomationConnection, testMode,
6466                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6467                    isRestrictedBackupMode || !normalMode, app.persistent,
6468                    new Configuration(mConfiguration), app.compat,
6469                    getCommonServicesLocked(app.isolated),
6470                    mCoreSettingsObserver.getCoreSettingsLocked());
6471            updateLruProcessLocked(app, false, null);
6472            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6473        } catch (Exception e) {
6474            // todo: Yikes!  What should we do?  For now we will try to
6475            // start another process, but that could easily get us in
6476            // an infinite loop of restarting processes...
6477            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6478
6479            app.resetPackageList(mProcessStats);
6480            app.unlinkDeathRecipient();
6481            startProcessLocked(app, "bind fail", processName);
6482            return false;
6483        }
6484
6485        // Remove this record from the list of starting applications.
6486        mPersistentStartingProcesses.remove(app);
6487        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6488                "Attach application locked removing on hold: " + app);
6489        mProcessesOnHold.remove(app);
6490
6491        boolean badApp = false;
6492        boolean didSomething = false;
6493
6494        // See if the top visible activity is waiting to run in this process...
6495        if (normalMode) {
6496            try {
6497                if (mStackSupervisor.attachApplicationLocked(app)) {
6498                    didSomething = true;
6499                }
6500            } catch (Exception e) {
6501                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6502                badApp = true;
6503            }
6504        }
6505
6506        // Find any services that should be running in this process...
6507        if (!badApp) {
6508            try {
6509                didSomething |= mServices.attachApplicationLocked(app, processName);
6510            } catch (Exception e) {
6511                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6512                badApp = true;
6513            }
6514        }
6515
6516        // Check if a next-broadcast receiver is in this process...
6517        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6518            try {
6519                didSomething |= sendPendingBroadcastsLocked(app);
6520            } catch (Exception e) {
6521                // If the app died trying to launch the receiver we declare it 'bad'
6522                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6523                badApp = true;
6524            }
6525        }
6526
6527        // Check whether the next backup agent is in this process...
6528        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6529            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6530                    "New app is backup target, launching agent for " + app);
6531            notifyPackageUse(mBackupTarget.appInfo.packageName,
6532                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6533            try {
6534                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6535                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6536                        mBackupTarget.backupMode);
6537            } catch (Exception e) {
6538                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6539                badApp = true;
6540            }
6541        }
6542
6543        if (badApp) {
6544            app.kill("error during init", true);
6545            handleAppDiedLocked(app, false, true);
6546            return false;
6547        }
6548
6549        if (!didSomething) {
6550            updateOomAdjLocked();
6551        }
6552
6553        return true;
6554    }
6555
6556    @Override
6557    public final void attachApplication(IApplicationThread thread) {
6558        synchronized (this) {
6559            int callingPid = Binder.getCallingPid();
6560            final long origId = Binder.clearCallingIdentity();
6561            attachApplicationLocked(thread, callingPid);
6562            Binder.restoreCallingIdentity(origId);
6563        }
6564    }
6565
6566    @Override
6567    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6568        final long origId = Binder.clearCallingIdentity();
6569        synchronized (this) {
6570            ActivityStack stack = ActivityRecord.getStackLocked(token);
6571            if (stack != null) {
6572                ActivityRecord r =
6573                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6574                if (stopProfiling) {
6575                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6576                        try {
6577                            mProfileFd.close();
6578                        } catch (IOException e) {
6579                        }
6580                        clearProfilerLocked();
6581                    }
6582                }
6583            }
6584        }
6585        Binder.restoreCallingIdentity(origId);
6586    }
6587
6588    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6589        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6590                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6591    }
6592
6593    void enableScreenAfterBoot() {
6594        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6595                SystemClock.uptimeMillis());
6596        mWindowManager.enableScreenAfterBoot();
6597
6598        synchronized (this) {
6599            updateEventDispatchingLocked();
6600        }
6601    }
6602
6603    @Override
6604    public void showBootMessage(final CharSequence msg, final boolean always) {
6605        if (Binder.getCallingUid() != Process.myUid()) {
6606            // These days only the core system can call this, so apps can't get in
6607            // the way of what we show about running them.
6608        }
6609        mWindowManager.showBootMessage(msg, always);
6610    }
6611
6612    @Override
6613    public void keyguardWaitingForActivityDrawn() {
6614        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6615        final long token = Binder.clearCallingIdentity();
6616        try {
6617            synchronized (this) {
6618                if (DEBUG_LOCKSCREEN) logLockScreen("");
6619                mWindowManager.keyguardWaitingForActivityDrawn();
6620                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6621                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6622                    updateSleepIfNeededLocked();
6623                }
6624            }
6625        } finally {
6626            Binder.restoreCallingIdentity(token);
6627        }
6628    }
6629
6630    @Override
6631    public void keyguardGoingAway(int flags) {
6632        enforceNotIsolatedCaller("keyguardGoingAway");
6633        final long token = Binder.clearCallingIdentity();
6634        try {
6635            synchronized (this) {
6636                if (DEBUG_LOCKSCREEN) logLockScreen("");
6637                mWindowManager.keyguardGoingAway(flags);
6638                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6639                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6640                    updateSleepIfNeededLocked();
6641
6642                    // Some stack visibility might change (e.g. docked stack)
6643                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6644                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6645                }
6646            }
6647        } finally {
6648            Binder.restoreCallingIdentity(token);
6649        }
6650    }
6651
6652    final void finishBooting() {
6653        synchronized (this) {
6654            if (!mBootAnimationComplete) {
6655                mCallFinishBooting = true;
6656                return;
6657            }
6658            mCallFinishBooting = false;
6659        }
6660
6661        ArraySet<String> completedIsas = new ArraySet<String>();
6662        for (String abi : Build.SUPPORTED_ABIS) {
6663            Process.establishZygoteConnectionForAbi(abi);
6664            final String instructionSet = VMRuntime.getInstructionSet(abi);
6665            if (!completedIsas.contains(instructionSet)) {
6666                try {
6667                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6668                } catch (InstallerException e) {
6669                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6670                            e.getMessage() +")");
6671                }
6672                completedIsas.add(instructionSet);
6673            }
6674        }
6675
6676        IntentFilter pkgFilter = new IntentFilter();
6677        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6678        pkgFilter.addDataScheme("package");
6679        mContext.registerReceiver(new BroadcastReceiver() {
6680            @Override
6681            public void onReceive(Context context, Intent intent) {
6682                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6683                if (pkgs != null) {
6684                    for (String pkg : pkgs) {
6685                        synchronized (ActivityManagerService.this) {
6686                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6687                                    0, "query restart")) {
6688                                setResultCode(Activity.RESULT_OK);
6689                                return;
6690                            }
6691                        }
6692                    }
6693                }
6694            }
6695        }, pkgFilter);
6696
6697        IntentFilter dumpheapFilter = new IntentFilter();
6698        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6699        mContext.registerReceiver(new BroadcastReceiver() {
6700            @Override
6701            public void onReceive(Context context, Intent intent) {
6702                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6703                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6704                } else {
6705                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6706                }
6707            }
6708        }, dumpheapFilter);
6709
6710        // Let system services know.
6711        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6712
6713        synchronized (this) {
6714            // Ensure that any processes we had put on hold are now started
6715            // up.
6716            final int NP = mProcessesOnHold.size();
6717            if (NP > 0) {
6718                ArrayList<ProcessRecord> procs =
6719                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6720                for (int ip=0; ip<NP; ip++) {
6721                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6722                            + procs.get(ip));
6723                    startProcessLocked(procs.get(ip), "on-hold", null);
6724                }
6725            }
6726
6727            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6728                // Start looking for apps that are abusing wake locks.
6729                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6730                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6731                // Tell anyone interested that we are done booting!
6732                SystemProperties.set("sys.boot_completed", "1");
6733
6734                // And trigger dev.bootcomplete if we are not showing encryption progress
6735                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6736                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6737                    SystemProperties.set("dev.bootcomplete", "1");
6738                }
6739                mUserController.sendBootCompletedLocked(
6740                        new IIntentReceiver.Stub() {
6741                            @Override
6742                            public void performReceive(Intent intent, int resultCode,
6743                                    String data, Bundle extras, boolean ordered,
6744                                    boolean sticky, int sendingUser) {
6745                                synchronized (ActivityManagerService.this) {
6746                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6747                                            true, false);
6748                                }
6749                            }
6750                        });
6751                scheduleStartProfilesLocked();
6752            }
6753        }
6754    }
6755
6756    @Override
6757    public void bootAnimationComplete() {
6758        final boolean callFinishBooting;
6759        synchronized (this) {
6760            callFinishBooting = mCallFinishBooting;
6761            mBootAnimationComplete = true;
6762        }
6763        if (callFinishBooting) {
6764            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6765            finishBooting();
6766            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6767        }
6768    }
6769
6770    final void ensureBootCompleted() {
6771        boolean booting;
6772        boolean enableScreen;
6773        synchronized (this) {
6774            booting = mBooting;
6775            mBooting = false;
6776            enableScreen = !mBooted;
6777            mBooted = true;
6778        }
6779
6780        if (booting) {
6781            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6782            finishBooting();
6783            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6784        }
6785
6786        if (enableScreen) {
6787            enableScreenAfterBoot();
6788        }
6789    }
6790
6791    @Override
6792    public final void activityResumed(IBinder token) {
6793        final long origId = Binder.clearCallingIdentity();
6794        synchronized(this) {
6795            ActivityStack stack = ActivityRecord.getStackLocked(token);
6796            if (stack != null) {
6797                stack.activityResumedLocked(token);
6798            }
6799        }
6800        Binder.restoreCallingIdentity(origId);
6801    }
6802
6803    @Override
6804    public final void activityPaused(IBinder token) {
6805        final long origId = Binder.clearCallingIdentity();
6806        synchronized(this) {
6807            ActivityStack stack = ActivityRecord.getStackLocked(token);
6808            if (stack != null) {
6809                stack.activityPausedLocked(token, false);
6810            }
6811        }
6812        Binder.restoreCallingIdentity(origId);
6813    }
6814
6815    @Override
6816    public final void activityStopped(IBinder token, Bundle icicle,
6817            PersistableBundle persistentState, CharSequence description) {
6818        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6819
6820        // Refuse possible leaked file descriptors
6821        if (icicle != null && icicle.hasFileDescriptors()) {
6822            throw new IllegalArgumentException("File descriptors passed in Bundle");
6823        }
6824
6825        final long origId = Binder.clearCallingIdentity();
6826
6827        synchronized (this) {
6828            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6829            if (r != null) {
6830                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6831            }
6832        }
6833
6834        trimApplications();
6835
6836        Binder.restoreCallingIdentity(origId);
6837    }
6838
6839    @Override
6840    public final void activityDestroyed(IBinder token) {
6841        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6842        synchronized (this) {
6843            ActivityStack stack = ActivityRecord.getStackLocked(token);
6844            if (stack != null) {
6845                stack.activityDestroyedLocked(token, "activityDestroyed");
6846            }
6847        }
6848    }
6849
6850    @Override
6851    public final void activityRelaunched(IBinder token) {
6852        final long origId = Binder.clearCallingIdentity();
6853        synchronized (this) {
6854            mStackSupervisor.activityRelaunchedLocked(token);
6855        }
6856        Binder.restoreCallingIdentity(origId);
6857    }
6858
6859    @Override
6860    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6861            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6862        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6863                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6864        synchronized (this) {
6865            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6866            if (record == null) {
6867                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6868                        + "found for: " + token);
6869            }
6870            record.setSizeConfigurations(horizontalSizeConfiguration,
6871                    verticalSizeConfigurations, smallestSizeConfigurations);
6872        }
6873    }
6874
6875    @Override
6876    public final void backgroundResourcesReleased(IBinder token) {
6877        final long origId = Binder.clearCallingIdentity();
6878        try {
6879            synchronized (this) {
6880                ActivityStack stack = ActivityRecord.getStackLocked(token);
6881                if (stack != null) {
6882                    stack.backgroundResourcesReleased();
6883                }
6884            }
6885        } finally {
6886            Binder.restoreCallingIdentity(origId);
6887        }
6888    }
6889
6890    @Override
6891    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6892        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6893    }
6894
6895    @Override
6896    public final void notifyEnterAnimationComplete(IBinder token) {
6897        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6898    }
6899
6900    @Override
6901    public String getCallingPackage(IBinder token) {
6902        synchronized (this) {
6903            ActivityRecord r = getCallingRecordLocked(token);
6904            return r != null ? r.info.packageName : null;
6905        }
6906    }
6907
6908    @Override
6909    public ComponentName getCallingActivity(IBinder token) {
6910        synchronized (this) {
6911            ActivityRecord r = getCallingRecordLocked(token);
6912            return r != null ? r.intent.getComponent() : null;
6913        }
6914    }
6915
6916    private ActivityRecord getCallingRecordLocked(IBinder token) {
6917        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6918        if (r == null) {
6919            return null;
6920        }
6921        return r.resultTo;
6922    }
6923
6924    @Override
6925    public ComponentName getActivityClassForToken(IBinder token) {
6926        synchronized(this) {
6927            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6928            if (r == null) {
6929                return null;
6930            }
6931            return r.intent.getComponent();
6932        }
6933    }
6934
6935    @Override
6936    public String getPackageForToken(IBinder token) {
6937        synchronized(this) {
6938            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6939            if (r == null) {
6940                return null;
6941            }
6942            return r.packageName;
6943        }
6944    }
6945
6946    @Override
6947    public boolean isRootVoiceInteraction(IBinder token) {
6948        synchronized(this) {
6949            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6950            if (r == null) {
6951                return false;
6952            }
6953            return r.rootVoiceInteraction;
6954        }
6955    }
6956
6957    @Override
6958    public IIntentSender getIntentSender(int type,
6959            String packageName, IBinder token, String resultWho,
6960            int requestCode, Intent[] intents, String[] resolvedTypes,
6961            int flags, Bundle bOptions, int userId) {
6962        enforceNotIsolatedCaller("getIntentSender");
6963        // Refuse possible leaked file descriptors
6964        if (intents != null) {
6965            if (intents.length < 1) {
6966                throw new IllegalArgumentException("Intents array length must be >= 1");
6967            }
6968            for (int i=0; i<intents.length; i++) {
6969                Intent intent = intents[i];
6970                if (intent != null) {
6971                    if (intent.hasFileDescriptors()) {
6972                        throw new IllegalArgumentException("File descriptors passed in Intent");
6973                    }
6974                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6975                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6976                        throw new IllegalArgumentException(
6977                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6978                    }
6979                    intents[i] = new Intent(intent);
6980                }
6981            }
6982            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6983                throw new IllegalArgumentException(
6984                        "Intent array length does not match resolvedTypes length");
6985            }
6986        }
6987        if (bOptions != null) {
6988            if (bOptions.hasFileDescriptors()) {
6989                throw new IllegalArgumentException("File descriptors passed in options");
6990            }
6991        }
6992
6993        synchronized(this) {
6994            int callingUid = Binder.getCallingUid();
6995            int origUserId = userId;
6996            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6997                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6998                    ALLOW_NON_FULL, "getIntentSender", null);
6999            if (origUserId == UserHandle.USER_CURRENT) {
7000                // We don't want to evaluate this until the pending intent is
7001                // actually executed.  However, we do want to always do the
7002                // security checking for it above.
7003                userId = UserHandle.USER_CURRENT;
7004            }
7005            try {
7006                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7007                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7008                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7009                    if (!UserHandle.isSameApp(callingUid, uid)) {
7010                        String msg = "Permission Denial: getIntentSender() from pid="
7011                            + Binder.getCallingPid()
7012                            + ", uid=" + Binder.getCallingUid()
7013                            + ", (need uid=" + uid + ")"
7014                            + " is not allowed to send as package " + packageName;
7015                        Slog.w(TAG, msg);
7016                        throw new SecurityException(msg);
7017                    }
7018                }
7019
7020                return getIntentSenderLocked(type, packageName, callingUid, userId,
7021                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7022
7023            } catch (RemoteException e) {
7024                throw new SecurityException(e);
7025            }
7026        }
7027    }
7028
7029    IIntentSender getIntentSenderLocked(int type, String packageName,
7030            int callingUid, int userId, IBinder token, String resultWho,
7031            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7032            Bundle bOptions) {
7033        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7034        ActivityRecord activity = null;
7035        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7036            activity = ActivityRecord.isInStackLocked(token);
7037            if (activity == null) {
7038                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7039                return null;
7040            }
7041            if (activity.finishing) {
7042                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7043                return null;
7044            }
7045        }
7046
7047        // We're going to be splicing together extras before sending, so we're
7048        // okay poking into any contained extras.
7049        if (intents != null) {
7050            for (int i = 0; i < intents.length; i++) {
7051                intents[i].setDefusable(true);
7052            }
7053        }
7054        Bundle.setDefusable(bOptions, true);
7055
7056        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7057        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7058        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7059        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7060                |PendingIntent.FLAG_UPDATE_CURRENT);
7061
7062        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7063                type, packageName, activity, resultWho,
7064                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7065        WeakReference<PendingIntentRecord> ref;
7066        ref = mIntentSenderRecords.get(key);
7067        PendingIntentRecord rec = ref != null ? ref.get() : null;
7068        if (rec != null) {
7069            if (!cancelCurrent) {
7070                if (updateCurrent) {
7071                    if (rec.key.requestIntent != null) {
7072                        rec.key.requestIntent.replaceExtras(intents != null ?
7073                                intents[intents.length - 1] : null);
7074                    }
7075                    if (intents != null) {
7076                        intents[intents.length-1] = rec.key.requestIntent;
7077                        rec.key.allIntents = intents;
7078                        rec.key.allResolvedTypes = resolvedTypes;
7079                    } else {
7080                        rec.key.allIntents = null;
7081                        rec.key.allResolvedTypes = null;
7082                    }
7083                }
7084                return rec;
7085            }
7086            rec.canceled = true;
7087            mIntentSenderRecords.remove(key);
7088        }
7089        if (noCreate) {
7090            return rec;
7091        }
7092        rec = new PendingIntentRecord(this, key, callingUid);
7093        mIntentSenderRecords.put(key, rec.ref);
7094        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7095            if (activity.pendingResults == null) {
7096                activity.pendingResults
7097                        = new HashSet<WeakReference<PendingIntentRecord>>();
7098            }
7099            activity.pendingResults.add(rec.ref);
7100        }
7101        return rec;
7102    }
7103
7104    @Override
7105    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7106            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7107        if (target instanceof PendingIntentRecord) {
7108            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7109                    finishedReceiver, requiredPermission, options);
7110        } else {
7111            if (intent == null) {
7112                // Weird case: someone has given us their own custom IIntentSender, and now
7113                // they have someone else trying to send to it but of course this isn't
7114                // really a PendingIntent, so there is no base Intent, and the caller isn't
7115                // supplying an Intent... but we never want to dispatch a null Intent to
7116                // a receiver, so um...  let's make something up.
7117                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7118                intent = new Intent(Intent.ACTION_MAIN);
7119            }
7120            try {
7121                target.send(code, intent, resolvedType, null, requiredPermission, options);
7122            } catch (RemoteException e) {
7123            }
7124            // Platform code can rely on getting a result back when the send is done, but if
7125            // this intent sender is from outside of the system we can't rely on it doing that.
7126            // So instead we don't give it the result receiver, and instead just directly
7127            // report the finish immediately.
7128            if (finishedReceiver != null) {
7129                try {
7130                    finishedReceiver.performReceive(intent, 0,
7131                            null, null, false, false, UserHandle.getCallingUserId());
7132                } catch (RemoteException e) {
7133                }
7134            }
7135            return 0;
7136        }
7137    }
7138
7139    /**
7140     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7141     *
7142     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7143     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7144     */
7145    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7146        if (DEBUG_WHITELISTS) {
7147            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7148                    + targetUid + ", " + duration + ")");
7149        }
7150        synchronized (mPidsSelfLocked) {
7151            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7152            if (pr == null) {
7153                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7154                return;
7155            }
7156            if (!pr.whitelistManager) {
7157                if (DEBUG_WHITELISTS) {
7158                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7159                            + callerPid + " is not allowed");
7160                }
7161                return;
7162            }
7163        }
7164
7165        final long token = Binder.clearCallingIdentity();
7166        try {
7167            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7168                    true, "pe from uid:" + callerUid);
7169        } finally {
7170            Binder.restoreCallingIdentity(token);
7171        }
7172    }
7173
7174    @Override
7175    public void cancelIntentSender(IIntentSender sender) {
7176        if (!(sender instanceof PendingIntentRecord)) {
7177            return;
7178        }
7179        synchronized(this) {
7180            PendingIntentRecord rec = (PendingIntentRecord)sender;
7181            try {
7182                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7183                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7184                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7185                    String msg = "Permission Denial: cancelIntentSender() from pid="
7186                        + Binder.getCallingPid()
7187                        + ", uid=" + Binder.getCallingUid()
7188                        + " is not allowed to cancel packges "
7189                        + rec.key.packageName;
7190                    Slog.w(TAG, msg);
7191                    throw new SecurityException(msg);
7192                }
7193            } catch (RemoteException e) {
7194                throw new SecurityException(e);
7195            }
7196            cancelIntentSenderLocked(rec, true);
7197        }
7198    }
7199
7200    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7201        rec.canceled = true;
7202        mIntentSenderRecords.remove(rec.key);
7203        if (cleanActivity && rec.key.activity != null) {
7204            rec.key.activity.pendingResults.remove(rec.ref);
7205        }
7206    }
7207
7208    @Override
7209    public String getPackageForIntentSender(IIntentSender pendingResult) {
7210        if (!(pendingResult instanceof PendingIntentRecord)) {
7211            return null;
7212        }
7213        try {
7214            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7215            return res.key.packageName;
7216        } catch (ClassCastException e) {
7217        }
7218        return null;
7219    }
7220
7221    @Override
7222    public int getUidForIntentSender(IIntentSender sender) {
7223        if (sender instanceof PendingIntentRecord) {
7224            try {
7225                PendingIntentRecord res = (PendingIntentRecord)sender;
7226                return res.uid;
7227            } catch (ClassCastException e) {
7228            }
7229        }
7230        return -1;
7231    }
7232
7233    @Override
7234    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7235        if (!(pendingResult instanceof PendingIntentRecord)) {
7236            return false;
7237        }
7238        try {
7239            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7240            if (res.key.allIntents == null) {
7241                return false;
7242            }
7243            for (int i=0; i<res.key.allIntents.length; i++) {
7244                Intent intent = res.key.allIntents[i];
7245                if (intent.getPackage() != null && intent.getComponent() != null) {
7246                    return false;
7247                }
7248            }
7249            return true;
7250        } catch (ClassCastException e) {
7251        }
7252        return false;
7253    }
7254
7255    @Override
7256    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7257        if (!(pendingResult instanceof PendingIntentRecord)) {
7258            return false;
7259        }
7260        try {
7261            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7262            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7263                return true;
7264            }
7265            return false;
7266        } catch (ClassCastException e) {
7267        }
7268        return false;
7269    }
7270
7271    @Override
7272    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7273        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7274                "getIntentForIntentSender()");
7275        if (!(pendingResult instanceof PendingIntentRecord)) {
7276            return null;
7277        }
7278        try {
7279            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7280            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7281        } catch (ClassCastException e) {
7282        }
7283        return null;
7284    }
7285
7286    @Override
7287    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7288        if (!(pendingResult instanceof PendingIntentRecord)) {
7289            return null;
7290        }
7291        try {
7292            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7293            synchronized (this) {
7294                return getTagForIntentSenderLocked(res, prefix);
7295            }
7296        } catch (ClassCastException e) {
7297        }
7298        return null;
7299    }
7300
7301    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7302        final Intent intent = res.key.requestIntent;
7303        if (intent != null) {
7304            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7305                    || res.lastTagPrefix.equals(prefix))) {
7306                return res.lastTag;
7307            }
7308            res.lastTagPrefix = prefix;
7309            final StringBuilder sb = new StringBuilder(128);
7310            if (prefix != null) {
7311                sb.append(prefix);
7312            }
7313            if (intent.getAction() != null) {
7314                sb.append(intent.getAction());
7315            } else if (intent.getComponent() != null) {
7316                intent.getComponent().appendShortString(sb);
7317            } else {
7318                sb.append("?");
7319            }
7320            return res.lastTag = sb.toString();
7321        }
7322        return null;
7323    }
7324
7325    @Override
7326    public void setProcessLimit(int max) {
7327        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7328                "setProcessLimit()");
7329        synchronized (this) {
7330            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7331            mProcessLimitOverride = max;
7332        }
7333        trimApplications();
7334    }
7335
7336    @Override
7337    public int getProcessLimit() {
7338        synchronized (this) {
7339            return mProcessLimitOverride;
7340        }
7341    }
7342
7343    void foregroundTokenDied(ForegroundToken token) {
7344        synchronized (ActivityManagerService.this) {
7345            synchronized (mPidsSelfLocked) {
7346                ForegroundToken cur
7347                    = mForegroundProcesses.get(token.pid);
7348                if (cur != token) {
7349                    return;
7350                }
7351                mForegroundProcesses.remove(token.pid);
7352                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7353                if (pr == null) {
7354                    return;
7355                }
7356                pr.forcingToForeground = null;
7357                updateProcessForegroundLocked(pr, false, false);
7358            }
7359            updateOomAdjLocked();
7360        }
7361    }
7362
7363    @Override
7364    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7365        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7366                "setProcessForeground()");
7367        synchronized(this) {
7368            boolean changed = false;
7369
7370            synchronized (mPidsSelfLocked) {
7371                ProcessRecord pr = mPidsSelfLocked.get(pid);
7372                if (pr == null && isForeground) {
7373                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7374                    return;
7375                }
7376                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7377                if (oldToken != null) {
7378                    oldToken.token.unlinkToDeath(oldToken, 0);
7379                    mForegroundProcesses.remove(pid);
7380                    if (pr != null) {
7381                        pr.forcingToForeground = null;
7382                    }
7383                    changed = true;
7384                }
7385                if (isForeground && token != null) {
7386                    ForegroundToken newToken = new ForegroundToken() {
7387                        @Override
7388                        public void binderDied() {
7389                            foregroundTokenDied(this);
7390                        }
7391                    };
7392                    newToken.pid = pid;
7393                    newToken.token = token;
7394                    try {
7395                        token.linkToDeath(newToken, 0);
7396                        mForegroundProcesses.put(pid, newToken);
7397                        pr.forcingToForeground = token;
7398                        changed = true;
7399                    } catch (RemoteException e) {
7400                        // If the process died while doing this, we will later
7401                        // do the cleanup with the process death link.
7402                    }
7403                }
7404            }
7405
7406            if (changed) {
7407                updateOomAdjLocked();
7408            }
7409        }
7410    }
7411
7412    @Override
7413    public boolean isAppForeground(int uid) throws RemoteException {
7414        synchronized (this) {
7415            UidRecord uidRec = mActiveUids.get(uid);
7416            if (uidRec == null || uidRec.idle) {
7417                return false;
7418            }
7419            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7420        }
7421    }
7422
7423    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7424    // be guarded by permission checking.
7425    int getUidState(int uid) {
7426        synchronized (this) {
7427            UidRecord uidRec = mActiveUids.get(uid);
7428            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7429        }
7430    }
7431
7432    @Override
7433    public boolean isInMultiWindowMode(IBinder token) {
7434        final long origId = Binder.clearCallingIdentity();
7435        try {
7436            synchronized(this) {
7437                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7438                if (r == null) {
7439                    return false;
7440                }
7441                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7442                return !r.task.mFullscreen;
7443            }
7444        } finally {
7445            Binder.restoreCallingIdentity(origId);
7446        }
7447    }
7448
7449    @Override
7450    public boolean isInPictureInPictureMode(IBinder token) {
7451        final long origId = Binder.clearCallingIdentity();
7452        try {
7453            synchronized(this) {
7454                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7455                if (stack == null) {
7456                    return false;
7457                }
7458                return stack.mStackId == PINNED_STACK_ID;
7459            }
7460        } finally {
7461            Binder.restoreCallingIdentity(origId);
7462        }
7463    }
7464
7465    @Override
7466    public void enterPictureInPictureMode(IBinder token) {
7467        final long origId = Binder.clearCallingIdentity();
7468        try {
7469            synchronized(this) {
7470                if (!mSupportsPictureInPicture) {
7471                    throw new IllegalStateException("enterPictureInPictureMode: "
7472                            + "Device doesn't support picture-in-picture mode.");
7473                }
7474
7475                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7476
7477                if (r == null) {
7478                    throw new IllegalStateException("enterPictureInPictureMode: "
7479                            + "Can't find activity for token=" + token);
7480                }
7481
7482                if (!r.supportsPictureInPicture()) {
7483                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7484                            + "Picture-In-Picture not supported for r=" + r);
7485                }
7486
7487                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7488                // current bounds.
7489                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7490                final Rect bounds = (pinnedStack != null)
7491                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7492
7493                mStackSupervisor.moveActivityToPinnedStackLocked(
7494                        r, "enterPictureInPictureMode", bounds);
7495            }
7496        } finally {
7497            Binder.restoreCallingIdentity(origId);
7498        }
7499    }
7500
7501    // =========================================================
7502    // PROCESS INFO
7503    // =========================================================
7504
7505    static class ProcessInfoService extends IProcessInfoService.Stub {
7506        final ActivityManagerService mActivityManagerService;
7507        ProcessInfoService(ActivityManagerService activityManagerService) {
7508            mActivityManagerService = activityManagerService;
7509        }
7510
7511        @Override
7512        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7513            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7514                    /*in*/ pids, /*out*/ states, null);
7515        }
7516
7517        @Override
7518        public void getProcessStatesAndOomScoresFromPids(
7519                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7520            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7521                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7522        }
7523    }
7524
7525    /**
7526     * For each PID in the given input array, write the current process state
7527     * for that process into the states array, or -1 to indicate that no
7528     * process with the given PID exists. If scores array is provided, write
7529     * the oom score for the process into the scores array, with INVALID_ADJ
7530     * indicating the PID doesn't exist.
7531     */
7532    public void getProcessStatesAndOomScoresForPIDs(
7533            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7534        if (scores != null) {
7535            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7536                    "getProcessStatesAndOomScoresForPIDs()");
7537        }
7538
7539        if (pids == null) {
7540            throw new NullPointerException("pids");
7541        } else if (states == null) {
7542            throw new NullPointerException("states");
7543        } else if (pids.length != states.length) {
7544            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7545        } else if (scores != null && pids.length != scores.length) {
7546            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7547        }
7548
7549        synchronized (mPidsSelfLocked) {
7550            for (int i = 0; i < pids.length; i++) {
7551                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7552                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7553                        pr.curProcState;
7554                if (scores != null) {
7555                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7556                }
7557            }
7558        }
7559    }
7560
7561    // =========================================================
7562    // PERMISSIONS
7563    // =========================================================
7564
7565    static class PermissionController extends IPermissionController.Stub {
7566        ActivityManagerService mActivityManagerService;
7567        PermissionController(ActivityManagerService activityManagerService) {
7568            mActivityManagerService = activityManagerService;
7569        }
7570
7571        @Override
7572        public boolean checkPermission(String permission, int pid, int uid) {
7573            return mActivityManagerService.checkPermission(permission, pid,
7574                    uid) == PackageManager.PERMISSION_GRANTED;
7575        }
7576
7577        @Override
7578        public String[] getPackagesForUid(int uid) {
7579            return mActivityManagerService.mContext.getPackageManager()
7580                    .getPackagesForUid(uid);
7581        }
7582
7583        @Override
7584        public boolean isRuntimePermission(String permission) {
7585            try {
7586                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7587                        .getPermissionInfo(permission, 0);
7588                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7589            } catch (NameNotFoundException nnfe) {
7590                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7591            }
7592            return false;
7593        }
7594    }
7595
7596    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7597        @Override
7598        public int checkComponentPermission(String permission, int pid, int uid,
7599                int owningUid, boolean exported) {
7600            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7601                    owningUid, exported);
7602        }
7603
7604        @Override
7605        public Object getAMSLock() {
7606            return ActivityManagerService.this;
7607        }
7608    }
7609
7610    /**
7611     * This can be called with or without the global lock held.
7612     */
7613    int checkComponentPermission(String permission, int pid, int uid,
7614            int owningUid, boolean exported) {
7615        if (pid == MY_PID) {
7616            return PackageManager.PERMISSION_GRANTED;
7617        }
7618        return ActivityManager.checkComponentPermission(permission, uid,
7619                owningUid, exported);
7620    }
7621
7622    /**
7623     * As the only public entry point for permissions checking, this method
7624     * can enforce the semantic that requesting a check on a null global
7625     * permission is automatically denied.  (Internally a null permission
7626     * string is used when calling {@link #checkComponentPermission} in cases
7627     * when only uid-based security is needed.)
7628     *
7629     * This can be called with or without the global lock held.
7630     */
7631    @Override
7632    public int checkPermission(String permission, int pid, int uid) {
7633        if (permission == null) {
7634            return PackageManager.PERMISSION_DENIED;
7635        }
7636        return checkComponentPermission(permission, pid, uid, -1, true);
7637    }
7638
7639    @Override
7640    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7641        if (permission == null) {
7642            return PackageManager.PERMISSION_DENIED;
7643        }
7644
7645        // We might be performing an operation on behalf of an indirect binder
7646        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7647        // client identity accordingly before proceeding.
7648        Identity tlsIdentity = sCallerIdentity.get();
7649        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7650            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7651                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7652            uid = tlsIdentity.uid;
7653            pid = tlsIdentity.pid;
7654        }
7655
7656        return checkComponentPermission(permission, pid, uid, -1, true);
7657    }
7658
7659    /**
7660     * Binder IPC calls go through the public entry point.
7661     * This can be called with or without the global lock held.
7662     */
7663    int checkCallingPermission(String permission) {
7664        return checkPermission(permission,
7665                Binder.getCallingPid(),
7666                UserHandle.getAppId(Binder.getCallingUid()));
7667    }
7668
7669    /**
7670     * This can be called with or without the global lock held.
7671     */
7672    void enforceCallingPermission(String permission, String func) {
7673        if (checkCallingPermission(permission)
7674                == PackageManager.PERMISSION_GRANTED) {
7675            return;
7676        }
7677
7678        String msg = "Permission Denial: " + func + " from pid="
7679                + Binder.getCallingPid()
7680                + ", uid=" + Binder.getCallingUid()
7681                + " requires " + permission;
7682        Slog.w(TAG, msg);
7683        throw new SecurityException(msg);
7684    }
7685
7686    /**
7687     * Determine if UID is holding permissions required to access {@link Uri} in
7688     * the given {@link ProviderInfo}. Final permission checking is always done
7689     * in {@link ContentProvider}.
7690     */
7691    private final boolean checkHoldingPermissionsLocked(
7692            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7693        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7694                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7695        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7696            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7697                    != PERMISSION_GRANTED) {
7698                return false;
7699            }
7700        }
7701        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7702    }
7703
7704    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7705            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7706        if (pi.applicationInfo.uid == uid) {
7707            return true;
7708        } else if (!pi.exported) {
7709            return false;
7710        }
7711
7712        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7713        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7714        try {
7715            // check if target holds top-level <provider> permissions
7716            if (!readMet && pi.readPermission != null && considerUidPermissions
7717                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7718                readMet = true;
7719            }
7720            if (!writeMet && pi.writePermission != null && considerUidPermissions
7721                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7722                writeMet = true;
7723            }
7724
7725            // track if unprotected read/write is allowed; any denied
7726            // <path-permission> below removes this ability
7727            boolean allowDefaultRead = pi.readPermission == null;
7728            boolean allowDefaultWrite = pi.writePermission == null;
7729
7730            // check if target holds any <path-permission> that match uri
7731            final PathPermission[] pps = pi.pathPermissions;
7732            if (pps != null) {
7733                final String path = grantUri.uri.getPath();
7734                int i = pps.length;
7735                while (i > 0 && (!readMet || !writeMet)) {
7736                    i--;
7737                    PathPermission pp = pps[i];
7738                    if (pp.match(path)) {
7739                        if (!readMet) {
7740                            final String pprperm = pp.getReadPermission();
7741                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7742                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7743                                    + ": match=" + pp.match(path)
7744                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7745                            if (pprperm != null) {
7746                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7747                                        == PERMISSION_GRANTED) {
7748                                    readMet = true;
7749                                } else {
7750                                    allowDefaultRead = false;
7751                                }
7752                            }
7753                        }
7754                        if (!writeMet) {
7755                            final String ppwperm = pp.getWritePermission();
7756                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7757                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7758                                    + ": match=" + pp.match(path)
7759                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7760                            if (ppwperm != null) {
7761                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7762                                        == PERMISSION_GRANTED) {
7763                                    writeMet = true;
7764                                } else {
7765                                    allowDefaultWrite = false;
7766                                }
7767                            }
7768                        }
7769                    }
7770                }
7771            }
7772
7773            // grant unprotected <provider> read/write, if not blocked by
7774            // <path-permission> above
7775            if (allowDefaultRead) readMet = true;
7776            if (allowDefaultWrite) writeMet = true;
7777
7778        } catch (RemoteException e) {
7779            return false;
7780        }
7781
7782        return readMet && writeMet;
7783    }
7784
7785    public int getAppStartMode(int uid, String packageName) {
7786        synchronized (this) {
7787            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7788        }
7789    }
7790
7791    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7792            boolean allowWhenForeground) {
7793        UidRecord uidRec = mActiveUids.get(uid);
7794        if (!mLenientBackgroundCheck) {
7795            if (!allowWhenForeground || uidRec == null
7796                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7797                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7798                        packageName) != AppOpsManager.MODE_ALLOWED) {
7799                    return ActivityManager.APP_START_MODE_DELAYED;
7800                }
7801            }
7802
7803        } else if (uidRec == null || uidRec.idle) {
7804            if (callingPid >= 0) {
7805                ProcessRecord proc;
7806                synchronized (mPidsSelfLocked) {
7807                    proc = mPidsSelfLocked.get(callingPid);
7808                }
7809                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7810                    // Whoever is instigating this is in the foreground, so we will allow it
7811                    // to go through.
7812                    return ActivityManager.APP_START_MODE_NORMAL;
7813                }
7814            }
7815            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7816                    != AppOpsManager.MODE_ALLOWED) {
7817                return ActivityManager.APP_START_MODE_DELAYED;
7818            }
7819        }
7820        return ActivityManager.APP_START_MODE_NORMAL;
7821    }
7822
7823    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7824        ProviderInfo pi = null;
7825        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7826        if (cpr != null) {
7827            pi = cpr.info;
7828        } else {
7829            try {
7830                pi = AppGlobals.getPackageManager().resolveContentProvider(
7831                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7832            } catch (RemoteException ex) {
7833            }
7834        }
7835        return pi;
7836    }
7837
7838    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7839        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7840        if (targetUris != null) {
7841            return targetUris.get(grantUri);
7842        }
7843        return null;
7844    }
7845
7846    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7847            String targetPkg, int targetUid, GrantUri grantUri) {
7848        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7849        if (targetUris == null) {
7850            targetUris = Maps.newArrayMap();
7851            mGrantedUriPermissions.put(targetUid, targetUris);
7852        }
7853
7854        UriPermission perm = targetUris.get(grantUri);
7855        if (perm == null) {
7856            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7857            targetUris.put(grantUri, perm);
7858        }
7859
7860        return perm;
7861    }
7862
7863    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7864            final int modeFlags) {
7865        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7866        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7867                : UriPermission.STRENGTH_OWNED;
7868
7869        // Root gets to do everything.
7870        if (uid == 0) {
7871            return true;
7872        }
7873
7874        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7875        if (perms == null) return false;
7876
7877        // First look for exact match
7878        final UriPermission exactPerm = perms.get(grantUri);
7879        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7880            return true;
7881        }
7882
7883        // No exact match, look for prefixes
7884        final int N = perms.size();
7885        for (int i = 0; i < N; i++) {
7886            final UriPermission perm = perms.valueAt(i);
7887            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7888                    && perm.getStrength(modeFlags) >= minStrength) {
7889                return true;
7890            }
7891        }
7892
7893        return false;
7894    }
7895
7896    /**
7897     * @param uri This uri must NOT contain an embedded userId.
7898     * @param userId The userId in which the uri is to be resolved.
7899     */
7900    @Override
7901    public int checkUriPermission(Uri uri, int pid, int uid,
7902            final int modeFlags, int userId, IBinder callerToken) {
7903        enforceNotIsolatedCaller("checkUriPermission");
7904
7905        // Another redirected-binder-call permissions check as in
7906        // {@link checkPermissionWithToken}.
7907        Identity tlsIdentity = sCallerIdentity.get();
7908        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7909            uid = tlsIdentity.uid;
7910            pid = tlsIdentity.pid;
7911        }
7912
7913        // Our own process gets to do everything.
7914        if (pid == MY_PID) {
7915            return PackageManager.PERMISSION_GRANTED;
7916        }
7917        synchronized (this) {
7918            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7919                    ? PackageManager.PERMISSION_GRANTED
7920                    : PackageManager.PERMISSION_DENIED;
7921        }
7922    }
7923
7924    /**
7925     * Check if the targetPkg can be granted permission to access uri by
7926     * the callingUid using the given modeFlags.  Throws a security exception
7927     * if callingUid is not allowed to do this.  Returns the uid of the target
7928     * if the URI permission grant should be performed; returns -1 if it is not
7929     * needed (for example targetPkg already has permission to access the URI).
7930     * If you already know the uid of the target, you can supply it in
7931     * lastTargetUid else set that to -1.
7932     */
7933    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7934            final int modeFlags, int lastTargetUid) {
7935        if (!Intent.isAccessUriMode(modeFlags)) {
7936            return -1;
7937        }
7938
7939        if (targetPkg != null) {
7940            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7941                    "Checking grant " + targetPkg + " permission to " + grantUri);
7942        }
7943
7944        final IPackageManager pm = AppGlobals.getPackageManager();
7945
7946        // If this is not a content: uri, we can't do anything with it.
7947        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7948            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7949                    "Can't grant URI permission for non-content URI: " + grantUri);
7950            return -1;
7951        }
7952
7953        final String authority = grantUri.uri.getAuthority();
7954        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7955        if (pi == null) {
7956            Slog.w(TAG, "No content provider found for permission check: " +
7957                    grantUri.uri.toSafeString());
7958            return -1;
7959        }
7960
7961        int targetUid = lastTargetUid;
7962        if (targetUid < 0 && targetPkg != null) {
7963            try {
7964                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7965                        UserHandle.getUserId(callingUid));
7966                if (targetUid < 0) {
7967                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7968                            "Can't grant URI permission no uid for: " + targetPkg);
7969                    return -1;
7970                }
7971            } catch (RemoteException ex) {
7972                return -1;
7973            }
7974        }
7975
7976        if (targetUid >= 0) {
7977            // First...  does the target actually need this permission?
7978            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7979                // No need to grant the target this permission.
7980                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7981                        "Target " + targetPkg + " already has full permission to " + grantUri);
7982                return -1;
7983            }
7984        } else {
7985            // First...  there is no target package, so can anyone access it?
7986            boolean allowed = pi.exported;
7987            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7988                if (pi.readPermission != null) {
7989                    allowed = false;
7990                }
7991            }
7992            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7993                if (pi.writePermission != null) {
7994                    allowed = false;
7995                }
7996            }
7997            if (allowed) {
7998                return -1;
7999            }
8000        }
8001
8002        /* There is a special cross user grant if:
8003         * - The target is on another user.
8004         * - Apps on the current user can access the uri without any uid permissions.
8005         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8006         * grant uri permissions.
8007         */
8008        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8009                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8010                modeFlags, false /*without considering the uid permissions*/);
8011
8012        // Second...  is the provider allowing granting of URI permissions?
8013        if (!specialCrossUserGrant) {
8014            if (!pi.grantUriPermissions) {
8015                throw new SecurityException("Provider " + pi.packageName
8016                        + "/" + pi.name
8017                        + " does not allow granting of Uri permissions (uri "
8018                        + grantUri + ")");
8019            }
8020            if (pi.uriPermissionPatterns != null) {
8021                final int N = pi.uriPermissionPatterns.length;
8022                boolean allowed = false;
8023                for (int i=0; i<N; i++) {
8024                    if (pi.uriPermissionPatterns[i] != null
8025                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8026                        allowed = true;
8027                        break;
8028                    }
8029                }
8030                if (!allowed) {
8031                    throw new SecurityException("Provider " + pi.packageName
8032                            + "/" + pi.name
8033                            + " does not allow granting of permission to path of Uri "
8034                            + grantUri);
8035                }
8036            }
8037        }
8038
8039        // Third...  does the caller itself have permission to access
8040        // this uri?
8041        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8042            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8043                // Require they hold a strong enough Uri permission
8044                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8045                    throw new SecurityException("Uid " + callingUid
8046                            + " does not have permission to uri " + grantUri);
8047                }
8048            }
8049        }
8050        return targetUid;
8051    }
8052
8053    /**
8054     * @param uri This uri must NOT contain an embedded userId.
8055     * @param userId The userId in which the uri is to be resolved.
8056     */
8057    @Override
8058    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8059            final int modeFlags, int userId) {
8060        enforceNotIsolatedCaller("checkGrantUriPermission");
8061        synchronized(this) {
8062            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8063                    new GrantUri(userId, uri, false), modeFlags, -1);
8064        }
8065    }
8066
8067    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8068            final int modeFlags, UriPermissionOwner owner) {
8069        if (!Intent.isAccessUriMode(modeFlags)) {
8070            return;
8071        }
8072
8073        // So here we are: the caller has the assumed permission
8074        // to the uri, and the target doesn't.  Let's now give this to
8075        // the target.
8076
8077        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8078                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8079
8080        final String authority = grantUri.uri.getAuthority();
8081        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8082        if (pi == null) {
8083            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8084            return;
8085        }
8086
8087        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8088            grantUri.prefix = true;
8089        }
8090        final UriPermission perm = findOrCreateUriPermissionLocked(
8091                pi.packageName, targetPkg, targetUid, grantUri);
8092        perm.grantModes(modeFlags, owner);
8093    }
8094
8095    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8096            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8097        if (targetPkg == null) {
8098            throw new NullPointerException("targetPkg");
8099        }
8100        int targetUid;
8101        final IPackageManager pm = AppGlobals.getPackageManager();
8102        try {
8103            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8104        } catch (RemoteException ex) {
8105            return;
8106        }
8107
8108        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8109                targetUid);
8110        if (targetUid < 0) {
8111            return;
8112        }
8113
8114        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8115                owner);
8116    }
8117
8118    static class NeededUriGrants extends ArrayList<GrantUri> {
8119        final String targetPkg;
8120        final int targetUid;
8121        final int flags;
8122
8123        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8124            this.targetPkg = targetPkg;
8125            this.targetUid = targetUid;
8126            this.flags = flags;
8127        }
8128    }
8129
8130    /**
8131     * Like checkGrantUriPermissionLocked, but takes an Intent.
8132     */
8133    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8134            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8135        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8136                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8137                + " clip=" + (intent != null ? intent.getClipData() : null)
8138                + " from " + intent + "; flags=0x"
8139                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8140
8141        if (targetPkg == null) {
8142            throw new NullPointerException("targetPkg");
8143        }
8144
8145        if (intent == null) {
8146            return null;
8147        }
8148        Uri data = intent.getData();
8149        ClipData clip = intent.getClipData();
8150        if (data == null && clip == null) {
8151            return null;
8152        }
8153        // Default userId for uris in the intent (if they don't specify it themselves)
8154        int contentUserHint = intent.getContentUserHint();
8155        if (contentUserHint == UserHandle.USER_CURRENT) {
8156            contentUserHint = UserHandle.getUserId(callingUid);
8157        }
8158        final IPackageManager pm = AppGlobals.getPackageManager();
8159        int targetUid;
8160        if (needed != null) {
8161            targetUid = needed.targetUid;
8162        } else {
8163            try {
8164                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8165                        targetUserId);
8166            } catch (RemoteException ex) {
8167                return null;
8168            }
8169            if (targetUid < 0) {
8170                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8171                        "Can't grant URI permission no uid for: " + targetPkg
8172                        + " on user " + targetUserId);
8173                return null;
8174            }
8175        }
8176        if (data != null) {
8177            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8178            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8179                    targetUid);
8180            if (targetUid > 0) {
8181                if (needed == null) {
8182                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8183                }
8184                needed.add(grantUri);
8185            }
8186        }
8187        if (clip != null) {
8188            for (int i=0; i<clip.getItemCount(); i++) {
8189                Uri uri = clip.getItemAt(i).getUri();
8190                if (uri != null) {
8191                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8192                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8193                            targetUid);
8194                    if (targetUid > 0) {
8195                        if (needed == null) {
8196                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8197                        }
8198                        needed.add(grantUri);
8199                    }
8200                } else {
8201                    Intent clipIntent = clip.getItemAt(i).getIntent();
8202                    if (clipIntent != null) {
8203                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8204                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8205                        if (newNeeded != null) {
8206                            needed = newNeeded;
8207                        }
8208                    }
8209                }
8210            }
8211        }
8212
8213        return needed;
8214    }
8215
8216    /**
8217     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8218     */
8219    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8220            UriPermissionOwner owner) {
8221        if (needed != null) {
8222            for (int i=0; i<needed.size(); i++) {
8223                GrantUri grantUri = needed.get(i);
8224                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8225                        grantUri, needed.flags, owner);
8226            }
8227        }
8228    }
8229
8230    void grantUriPermissionFromIntentLocked(int callingUid,
8231            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8232        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8233                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8234        if (needed == null) {
8235            return;
8236        }
8237
8238        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8239    }
8240
8241    /**
8242     * @param uri This uri must NOT contain an embedded userId.
8243     * @param userId The userId in which the uri is to be resolved.
8244     */
8245    @Override
8246    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8247            final int modeFlags, int userId) {
8248        enforceNotIsolatedCaller("grantUriPermission");
8249        GrantUri grantUri = new GrantUri(userId, uri, false);
8250        synchronized(this) {
8251            final ProcessRecord r = getRecordForAppLocked(caller);
8252            if (r == null) {
8253                throw new SecurityException("Unable to find app for caller "
8254                        + caller
8255                        + " when granting permission to uri " + grantUri);
8256            }
8257            if (targetPkg == null) {
8258                throw new IllegalArgumentException("null target");
8259            }
8260            if (grantUri == null) {
8261                throw new IllegalArgumentException("null uri");
8262            }
8263
8264            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8265                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8266                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8267                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8268
8269            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8270                    UserHandle.getUserId(r.uid));
8271        }
8272    }
8273
8274    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8275        if (perm.modeFlags == 0) {
8276            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8277                    perm.targetUid);
8278            if (perms != null) {
8279                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8280                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8281
8282                perms.remove(perm.uri);
8283                if (perms.isEmpty()) {
8284                    mGrantedUriPermissions.remove(perm.targetUid);
8285                }
8286            }
8287        }
8288    }
8289
8290    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8291        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8292                "Revoking all granted permissions to " + grantUri);
8293
8294        final IPackageManager pm = AppGlobals.getPackageManager();
8295        final String authority = grantUri.uri.getAuthority();
8296        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8297        if (pi == null) {
8298            Slog.w(TAG, "No content provider found for permission revoke: "
8299                    + grantUri.toSafeString());
8300            return;
8301        }
8302
8303        // Does the caller have this permission on the URI?
8304        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8305            // If they don't have direct access to the URI, then revoke any
8306            // ownerless URI permissions that have been granted to them.
8307            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8308            if (perms != null) {
8309                boolean persistChanged = false;
8310                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8311                    final UriPermission perm = it.next();
8312                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8313                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8314                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8315                                "Revoking non-owned " + perm.targetUid
8316                                + " permission to " + perm.uri);
8317                        persistChanged |= perm.revokeModes(
8318                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8319                        if (perm.modeFlags == 0) {
8320                            it.remove();
8321                        }
8322                    }
8323                }
8324                if (perms.isEmpty()) {
8325                    mGrantedUriPermissions.remove(callingUid);
8326                }
8327                if (persistChanged) {
8328                    schedulePersistUriGrants();
8329                }
8330            }
8331            return;
8332        }
8333
8334        boolean persistChanged = false;
8335
8336        // Go through all of the permissions and remove any that match.
8337        int N = mGrantedUriPermissions.size();
8338        for (int i = 0; i < N; i++) {
8339            final int targetUid = mGrantedUriPermissions.keyAt(i);
8340            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8341
8342            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8343                final UriPermission perm = it.next();
8344                if (perm.uri.sourceUserId == grantUri.sourceUserId
8345                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8346                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8347                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8348                    persistChanged |= perm.revokeModes(
8349                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8350                    if (perm.modeFlags == 0) {
8351                        it.remove();
8352                    }
8353                }
8354            }
8355
8356            if (perms.isEmpty()) {
8357                mGrantedUriPermissions.remove(targetUid);
8358                N--;
8359                i--;
8360            }
8361        }
8362
8363        if (persistChanged) {
8364            schedulePersistUriGrants();
8365        }
8366    }
8367
8368    /**
8369     * @param uri This uri must NOT contain an embedded userId.
8370     * @param userId The userId in which the uri is to be resolved.
8371     */
8372    @Override
8373    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8374            int userId) {
8375        enforceNotIsolatedCaller("revokeUriPermission");
8376        synchronized(this) {
8377            final ProcessRecord r = getRecordForAppLocked(caller);
8378            if (r == null) {
8379                throw new SecurityException("Unable to find app for caller "
8380                        + caller
8381                        + " when revoking permission to uri " + uri);
8382            }
8383            if (uri == null) {
8384                Slog.w(TAG, "revokeUriPermission: null uri");
8385                return;
8386            }
8387
8388            if (!Intent.isAccessUriMode(modeFlags)) {
8389                return;
8390            }
8391
8392            final String authority = uri.getAuthority();
8393            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8394            if (pi == null) {
8395                Slog.w(TAG, "No content provider found for permission revoke: "
8396                        + uri.toSafeString());
8397                return;
8398            }
8399
8400            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8401        }
8402    }
8403
8404    /**
8405     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8406     * given package.
8407     *
8408     * @param packageName Package name to match, or {@code null} to apply to all
8409     *            packages.
8410     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8411     *            to all users.
8412     * @param persistable If persistable grants should be removed.
8413     */
8414    private void removeUriPermissionsForPackageLocked(
8415            String packageName, int userHandle, boolean persistable) {
8416        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8417            throw new IllegalArgumentException("Must narrow by either package or user");
8418        }
8419
8420        boolean persistChanged = false;
8421
8422        int N = mGrantedUriPermissions.size();
8423        for (int i = 0; i < N; i++) {
8424            final int targetUid = mGrantedUriPermissions.keyAt(i);
8425            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8426
8427            // Only inspect grants matching user
8428            if (userHandle == UserHandle.USER_ALL
8429                    || userHandle == UserHandle.getUserId(targetUid)) {
8430                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8431                    final UriPermission perm = it.next();
8432
8433                    // Only inspect grants matching package
8434                    if (packageName == null || perm.sourcePkg.equals(packageName)
8435                            || perm.targetPkg.equals(packageName)) {
8436                        persistChanged |= perm.revokeModes(persistable
8437                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8438
8439                        // Only remove when no modes remain; any persisted grants
8440                        // will keep this alive.
8441                        if (perm.modeFlags == 0) {
8442                            it.remove();
8443                        }
8444                    }
8445                }
8446
8447                if (perms.isEmpty()) {
8448                    mGrantedUriPermissions.remove(targetUid);
8449                    N--;
8450                    i--;
8451                }
8452            }
8453        }
8454
8455        if (persistChanged) {
8456            schedulePersistUriGrants();
8457        }
8458    }
8459
8460    @Override
8461    public IBinder newUriPermissionOwner(String name) {
8462        enforceNotIsolatedCaller("newUriPermissionOwner");
8463        synchronized(this) {
8464            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8465            return owner.getExternalTokenLocked();
8466        }
8467    }
8468
8469    @Override
8470    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8471        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8472        synchronized(this) {
8473            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8474            if (r == null) {
8475                throw new IllegalArgumentException("Activity does not exist; token="
8476                        + activityToken);
8477            }
8478            return r.getUriPermissionsLocked().getExternalTokenLocked();
8479        }
8480    }
8481    /**
8482     * @param uri This uri must NOT contain an embedded userId.
8483     * @param sourceUserId The userId in which the uri is to be resolved.
8484     * @param targetUserId The userId of the app that receives the grant.
8485     */
8486    @Override
8487    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8488            final int modeFlags, int sourceUserId, int targetUserId) {
8489        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8490                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8491                "grantUriPermissionFromOwner", null);
8492        synchronized(this) {
8493            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8494            if (owner == null) {
8495                throw new IllegalArgumentException("Unknown owner: " + token);
8496            }
8497            if (fromUid != Binder.getCallingUid()) {
8498                if (Binder.getCallingUid() != Process.myUid()) {
8499                    // Only system code can grant URI permissions on behalf
8500                    // of other users.
8501                    throw new SecurityException("nice try");
8502                }
8503            }
8504            if (targetPkg == null) {
8505                throw new IllegalArgumentException("null target");
8506            }
8507            if (uri == null) {
8508                throw new IllegalArgumentException("null uri");
8509            }
8510
8511            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8512                    modeFlags, owner, targetUserId);
8513        }
8514    }
8515
8516    /**
8517     * @param uri This uri must NOT contain an embedded userId.
8518     * @param userId The userId in which the uri is to be resolved.
8519     */
8520    @Override
8521    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8522        synchronized(this) {
8523            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8524            if (owner == null) {
8525                throw new IllegalArgumentException("Unknown owner: " + token);
8526            }
8527
8528            if (uri == null) {
8529                owner.removeUriPermissionsLocked(mode);
8530            } else {
8531                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8532            }
8533        }
8534    }
8535
8536    private void schedulePersistUriGrants() {
8537        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8538            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8539                    10 * DateUtils.SECOND_IN_MILLIS);
8540        }
8541    }
8542
8543    private void writeGrantedUriPermissions() {
8544        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8545
8546        // Snapshot permissions so we can persist without lock
8547        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8548        synchronized (this) {
8549            final int size = mGrantedUriPermissions.size();
8550            for (int i = 0; i < size; i++) {
8551                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8552                for (UriPermission perm : perms.values()) {
8553                    if (perm.persistedModeFlags != 0) {
8554                        persist.add(perm.snapshot());
8555                    }
8556                }
8557            }
8558        }
8559
8560        FileOutputStream fos = null;
8561        try {
8562            fos = mGrantFile.startWrite();
8563
8564            XmlSerializer out = new FastXmlSerializer();
8565            out.setOutput(fos, StandardCharsets.UTF_8.name());
8566            out.startDocument(null, true);
8567            out.startTag(null, TAG_URI_GRANTS);
8568            for (UriPermission.Snapshot perm : persist) {
8569                out.startTag(null, TAG_URI_GRANT);
8570                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8571                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8572                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8573                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8574                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8575                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8576                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8577                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8578                out.endTag(null, TAG_URI_GRANT);
8579            }
8580            out.endTag(null, TAG_URI_GRANTS);
8581            out.endDocument();
8582
8583            mGrantFile.finishWrite(fos);
8584        } catch (IOException e) {
8585            if (fos != null) {
8586                mGrantFile.failWrite(fos);
8587            }
8588        }
8589    }
8590
8591    private void readGrantedUriPermissionsLocked() {
8592        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8593
8594        final long now = System.currentTimeMillis();
8595
8596        FileInputStream fis = null;
8597        try {
8598            fis = mGrantFile.openRead();
8599            final XmlPullParser in = Xml.newPullParser();
8600            in.setInput(fis, StandardCharsets.UTF_8.name());
8601
8602            int type;
8603            while ((type = in.next()) != END_DOCUMENT) {
8604                final String tag = in.getName();
8605                if (type == START_TAG) {
8606                    if (TAG_URI_GRANT.equals(tag)) {
8607                        final int sourceUserId;
8608                        final int targetUserId;
8609                        final int userHandle = readIntAttribute(in,
8610                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8611                        if (userHandle != UserHandle.USER_NULL) {
8612                            // For backwards compatibility.
8613                            sourceUserId = userHandle;
8614                            targetUserId = userHandle;
8615                        } else {
8616                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8617                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8618                        }
8619                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8620                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8621                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8622                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8623                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8624                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8625
8626                        // Sanity check that provider still belongs to source package
8627                        final ProviderInfo pi = getProviderInfoLocked(
8628                                uri.getAuthority(), sourceUserId);
8629                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8630                            int targetUid = -1;
8631                            try {
8632                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8633                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8634                            } catch (RemoteException e) {
8635                            }
8636                            if (targetUid != -1) {
8637                                final UriPermission perm = findOrCreateUriPermissionLocked(
8638                                        sourcePkg, targetPkg, targetUid,
8639                                        new GrantUri(sourceUserId, uri, prefix));
8640                                perm.initPersistedModes(modeFlags, createdTime);
8641                            }
8642                        } else {
8643                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8644                                    + " but instead found " + pi);
8645                        }
8646                    }
8647                }
8648            }
8649        } catch (FileNotFoundException e) {
8650            // Missing grants is okay
8651        } catch (IOException e) {
8652            Slog.wtf(TAG, "Failed reading Uri grants", e);
8653        } catch (XmlPullParserException e) {
8654            Slog.wtf(TAG, "Failed reading Uri grants", e);
8655        } finally {
8656            IoUtils.closeQuietly(fis);
8657        }
8658    }
8659
8660    /**
8661     * @param uri This uri must NOT contain an embedded userId.
8662     * @param userId The userId in which the uri is to be resolved.
8663     */
8664    @Override
8665    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8666        enforceNotIsolatedCaller("takePersistableUriPermission");
8667
8668        Preconditions.checkFlagsArgument(modeFlags,
8669                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8670
8671        synchronized (this) {
8672            final int callingUid = Binder.getCallingUid();
8673            boolean persistChanged = false;
8674            GrantUri grantUri = new GrantUri(userId, uri, false);
8675
8676            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8677                    new GrantUri(userId, uri, false));
8678            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8679                    new GrantUri(userId, uri, true));
8680
8681            final boolean exactValid = (exactPerm != null)
8682                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8683            final boolean prefixValid = (prefixPerm != null)
8684                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8685
8686            if (!(exactValid || prefixValid)) {
8687                throw new SecurityException("No persistable permission grants found for UID "
8688                        + callingUid + " and Uri " + grantUri.toSafeString());
8689            }
8690
8691            if (exactValid) {
8692                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8693            }
8694            if (prefixValid) {
8695                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8696            }
8697
8698            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8699
8700            if (persistChanged) {
8701                schedulePersistUriGrants();
8702            }
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 releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8712        enforceNotIsolatedCaller("releasePersistableUriPermission");
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
8721            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8722                    new GrantUri(userId, uri, false));
8723            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8724                    new GrantUri(userId, uri, true));
8725            if (exactPerm == null && prefixPerm == null) {
8726                throw new SecurityException("No permission grants found for UID " + callingUid
8727                        + " and Uri " + uri.toSafeString());
8728            }
8729
8730            if (exactPerm != null) {
8731                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8732                removeUriPermissionIfNeededLocked(exactPerm);
8733            }
8734            if (prefixPerm != null) {
8735                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8736                removeUriPermissionIfNeededLocked(prefixPerm);
8737            }
8738
8739            if (persistChanged) {
8740                schedulePersistUriGrants();
8741            }
8742        }
8743    }
8744
8745    /**
8746     * Prune any older {@link UriPermission} for the given UID until outstanding
8747     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8748     *
8749     * @return if any mutations occured that require persisting.
8750     */
8751    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8752        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8753        if (perms == null) return false;
8754        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8755
8756        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8757        for (UriPermission perm : perms.values()) {
8758            if (perm.persistedModeFlags != 0) {
8759                persisted.add(perm);
8760            }
8761        }
8762
8763        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8764        if (trimCount <= 0) return false;
8765
8766        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8767        for (int i = 0; i < trimCount; i++) {
8768            final UriPermission perm = persisted.get(i);
8769
8770            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8771                    "Trimming grant created at " + perm.persistedCreateTime);
8772
8773            perm.releasePersistableModes(~0);
8774            removeUriPermissionIfNeededLocked(perm);
8775        }
8776
8777        return true;
8778    }
8779
8780    @Override
8781    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8782            String packageName, boolean incoming) {
8783        enforceNotIsolatedCaller("getPersistedUriPermissions");
8784        Preconditions.checkNotNull(packageName, "packageName");
8785
8786        final int callingUid = Binder.getCallingUid();
8787        final IPackageManager pm = AppGlobals.getPackageManager();
8788        try {
8789            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8790                    UserHandle.getUserId(callingUid));
8791            if (packageUid != callingUid) {
8792                throw new SecurityException(
8793                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8794            }
8795        } catch (RemoteException e) {
8796            throw new SecurityException("Failed to verify package name ownership");
8797        }
8798
8799        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8800        synchronized (this) {
8801            if (incoming) {
8802                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8803                        callingUid);
8804                if (perms == null) {
8805                    Slog.w(TAG, "No permission grants found for " + packageName);
8806                } else {
8807                    for (UriPermission perm : perms.values()) {
8808                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8809                            result.add(perm.buildPersistedPublicApiObject());
8810                        }
8811                    }
8812                }
8813            } else {
8814                final int size = mGrantedUriPermissions.size();
8815                for (int i = 0; i < size; i++) {
8816                    final ArrayMap<GrantUri, UriPermission> perms =
8817                            mGrantedUriPermissions.valueAt(i);
8818                    for (UriPermission perm : perms.values()) {
8819                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8820                            result.add(perm.buildPersistedPublicApiObject());
8821                        }
8822                    }
8823                }
8824            }
8825        }
8826        return new ParceledListSlice<android.content.UriPermission>(result);
8827    }
8828
8829    @Override
8830    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8831            String packageName, int userId) {
8832        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8833                "getGrantedUriPermissions");
8834
8835        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8836        synchronized (this) {
8837            final int size = mGrantedUriPermissions.size();
8838            for (int i = 0; i < size; i++) {
8839                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8840                for (UriPermission perm : perms.values()) {
8841                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8842                            && perm.persistedModeFlags != 0) {
8843                        result.add(perm.buildPersistedPublicApiObject());
8844                    }
8845                }
8846            }
8847        }
8848        return new ParceledListSlice<android.content.UriPermission>(result);
8849    }
8850
8851    @Override
8852    public void clearGrantedUriPermissions(String packageName, int userId) {
8853        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8854                "clearGrantedUriPermissions");
8855        removeUriPermissionsForPackageLocked(packageName, userId, true);
8856    }
8857
8858    @Override
8859    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8860        synchronized (this) {
8861            ProcessRecord app =
8862                who != null ? getRecordForAppLocked(who) : null;
8863            if (app == null) return;
8864
8865            Message msg = Message.obtain();
8866            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8867            msg.obj = app;
8868            msg.arg1 = waiting ? 1 : 0;
8869            mUiHandler.sendMessage(msg);
8870        }
8871    }
8872
8873    @Override
8874    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8875        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8876        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8877        outInfo.availMem = Process.getFreeMemory();
8878        outInfo.totalMem = Process.getTotalMemory();
8879        outInfo.threshold = homeAppMem;
8880        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8881        outInfo.hiddenAppThreshold = cachedAppMem;
8882        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8883                ProcessList.SERVICE_ADJ);
8884        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8885                ProcessList.VISIBLE_APP_ADJ);
8886        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8887                ProcessList.FOREGROUND_APP_ADJ);
8888    }
8889
8890    // =========================================================
8891    // TASK MANAGEMENT
8892    // =========================================================
8893
8894    @Override
8895    public List<IAppTask> getAppTasks(String callingPackage) {
8896        int callingUid = Binder.getCallingUid();
8897        long ident = Binder.clearCallingIdentity();
8898
8899        synchronized(this) {
8900            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8901            try {
8902                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8903
8904                final int N = mRecentTasks.size();
8905                for (int i = 0; i < N; i++) {
8906                    TaskRecord tr = mRecentTasks.get(i);
8907                    // Skip tasks that do not match the caller.  We don't need to verify
8908                    // callingPackage, because we are also limiting to callingUid and know
8909                    // that will limit to the correct security sandbox.
8910                    if (tr.effectiveUid != callingUid) {
8911                        continue;
8912                    }
8913                    Intent intent = tr.getBaseIntent();
8914                    if (intent == null ||
8915                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8916                        continue;
8917                    }
8918                    ActivityManager.RecentTaskInfo taskInfo =
8919                            createRecentTaskInfoFromTaskRecord(tr);
8920                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8921                    list.add(taskImpl);
8922                }
8923            } finally {
8924                Binder.restoreCallingIdentity(ident);
8925            }
8926            return list;
8927        }
8928    }
8929
8930    @Override
8931    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8932        final int callingUid = Binder.getCallingUid();
8933        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8934
8935        synchronized(this) {
8936            if (DEBUG_ALL) Slog.v(
8937                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8938
8939            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8940                    callingUid);
8941
8942            // TODO: Improve with MRU list from all ActivityStacks.
8943            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8944        }
8945
8946        return list;
8947    }
8948
8949    /**
8950     * Creates a new RecentTaskInfo from a TaskRecord.
8951     */
8952    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8953        // Update the task description to reflect any changes in the task stack
8954        tr.updateTaskDescription();
8955
8956        // Compose the recent task info
8957        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8958        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8959        rti.persistentId = tr.taskId;
8960        rti.baseIntent = new Intent(tr.getBaseIntent());
8961        rti.origActivity = tr.origActivity;
8962        rti.realActivity = tr.realActivity;
8963        rti.description = tr.lastDescription;
8964        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8965        rti.userId = tr.userId;
8966        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8967        rti.firstActiveTime = tr.firstActiveTime;
8968        rti.lastActiveTime = tr.lastActiveTime;
8969        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8970        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8971        rti.numActivities = 0;
8972        if (tr.mBounds != null) {
8973            rti.bounds = new Rect(tr.mBounds);
8974        }
8975        rti.isDockable = tr.canGoInDockedStack();
8976        rti.resizeMode = tr.mResizeMode;
8977
8978        ActivityRecord base = null;
8979        ActivityRecord top = null;
8980        ActivityRecord tmp;
8981
8982        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8983            tmp = tr.mActivities.get(i);
8984            if (tmp.finishing) {
8985                continue;
8986            }
8987            base = tmp;
8988            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8989                top = base;
8990            }
8991            rti.numActivities++;
8992        }
8993
8994        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8995        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8996
8997        return rti;
8998    }
8999
9000    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9001        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9002                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9003        if (!allowed) {
9004            if (checkPermission(android.Manifest.permission.GET_TASKS,
9005                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9006                // Temporary compatibility: some existing apps on the system image may
9007                // still be requesting the old permission and not switched to the new
9008                // one; if so, we'll still allow them full access.  This means we need
9009                // to see if they are holding the old permission and are a system app.
9010                try {
9011                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9012                        allowed = true;
9013                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9014                                + " is using old GET_TASKS but privileged; allowing");
9015                    }
9016                } catch (RemoteException e) {
9017                }
9018            }
9019        }
9020        if (!allowed) {
9021            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9022                    + " does not hold REAL_GET_TASKS; limiting output");
9023        }
9024        return allowed;
9025    }
9026
9027    @Override
9028    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9029        final int callingUid = Binder.getCallingUid();
9030        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9031                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9032
9033        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9034        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9035        synchronized (this) {
9036            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9037                    callingUid);
9038            final boolean detailed = checkCallingPermission(
9039                    android.Manifest.permission.GET_DETAILED_TASKS)
9040                    == PackageManager.PERMISSION_GRANTED;
9041
9042            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9043                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9044                return Collections.emptyList();
9045            }
9046            mRecentTasks.loadUserRecentsLocked(userId);
9047
9048            final int recentsCount = mRecentTasks.size();
9049            ArrayList<ActivityManager.RecentTaskInfo> res =
9050                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9051
9052            final Set<Integer> includedUsers;
9053            if (includeProfiles) {
9054                includedUsers = mUserController.getProfileIds(userId);
9055            } else {
9056                includedUsers = new HashSet<>();
9057            }
9058            includedUsers.add(Integer.valueOf(userId));
9059
9060            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9061                TaskRecord tr = mRecentTasks.get(i);
9062                // Only add calling user or related users recent tasks
9063                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9064                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9065                    continue;
9066                }
9067
9068                if (tr.realActivitySuspended) {
9069                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9070                    continue;
9071                }
9072
9073                // Return the entry if desired by the caller.  We always return
9074                // the first entry, because callers always expect this to be the
9075                // foreground app.  We may filter others if the caller has
9076                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9077                // we should exclude the entry.
9078
9079                if (i == 0
9080                        || withExcluded
9081                        || (tr.intent == null)
9082                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9083                                == 0)) {
9084                    if (!allowed) {
9085                        // If the caller doesn't have the GET_TASKS permission, then only
9086                        // allow them to see a small subset of tasks -- their own and home.
9087                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9088                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9089                            continue;
9090                        }
9091                    }
9092                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9093                        if (tr.stack != null && tr.stack.isHomeStack()) {
9094                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9095                                    "Skipping, home stack task: " + tr);
9096                            continue;
9097                        }
9098                    }
9099                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9100                        final ActivityStack stack = tr.stack;
9101                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9102                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9103                                    "Skipping, top task in docked stack: " + tr);
9104                            continue;
9105                        }
9106                    }
9107                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9108                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9109                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9110                                    "Skipping, pinned stack task: " + tr);
9111                            continue;
9112                        }
9113                    }
9114                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9115                        // Don't include auto remove tasks that are finished or finishing.
9116                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9117                                "Skipping, auto-remove without activity: " + tr);
9118                        continue;
9119                    }
9120                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9121                            && !tr.isAvailable) {
9122                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9123                                "Skipping, unavail real act: " + tr);
9124                        continue;
9125                    }
9126
9127                    if (!tr.mUserSetupComplete) {
9128                        // Don't include task launched while user is not done setting-up.
9129                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9130                                "Skipping, user setup not complete: " + tr);
9131                        continue;
9132                    }
9133
9134                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9135                    if (!detailed) {
9136                        rti.baseIntent.replaceExtras((Bundle)null);
9137                    }
9138
9139                    res.add(rti);
9140                    maxNum--;
9141                }
9142            }
9143            return res;
9144        }
9145    }
9146
9147    @Override
9148    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9149        synchronized (this) {
9150            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9151                    "getTaskThumbnail()");
9152            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9153                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9154            if (tr != null) {
9155                return tr.getTaskThumbnailLocked();
9156            }
9157        }
9158        return null;
9159    }
9160
9161    @Override
9162    public int addAppTask(IBinder activityToken, Intent intent,
9163            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9164        final int callingUid = Binder.getCallingUid();
9165        final long callingIdent = Binder.clearCallingIdentity();
9166
9167        try {
9168            synchronized (this) {
9169                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9170                if (r == null) {
9171                    throw new IllegalArgumentException("Activity does not exist; token="
9172                            + activityToken);
9173                }
9174                ComponentName comp = intent.getComponent();
9175                if (comp == null) {
9176                    throw new IllegalArgumentException("Intent " + intent
9177                            + " must specify explicit component");
9178                }
9179                if (thumbnail.getWidth() != mThumbnailWidth
9180                        || thumbnail.getHeight() != mThumbnailHeight) {
9181                    throw new IllegalArgumentException("Bad thumbnail size: got "
9182                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9183                            + mThumbnailWidth + "x" + mThumbnailHeight);
9184                }
9185                if (intent.getSelector() != null) {
9186                    intent.setSelector(null);
9187                }
9188                if (intent.getSourceBounds() != null) {
9189                    intent.setSourceBounds(null);
9190                }
9191                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9192                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9193                        // The caller has added this as an auto-remove task...  that makes no
9194                        // sense, so turn off auto-remove.
9195                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9196                    }
9197                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9198                    // Must be a new task.
9199                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9200                }
9201                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9202                    mLastAddedTaskActivity = null;
9203                }
9204                ActivityInfo ainfo = mLastAddedTaskActivity;
9205                if (ainfo == null) {
9206                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9207                            comp, 0, UserHandle.getUserId(callingUid));
9208                    if (ainfo.applicationInfo.uid != callingUid) {
9209                        throw new SecurityException(
9210                                "Can't add task for another application: target uid="
9211                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9212                    }
9213                }
9214
9215                // Use the full screen as the context for the task thumbnail
9216                final Point displaySize = new Point();
9217                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9218                r.task.stack.getDisplaySize(displaySize);
9219                thumbnailInfo.taskWidth = displaySize.x;
9220                thumbnailInfo.taskHeight = displaySize.y;
9221                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9222
9223                TaskRecord task = new TaskRecord(this,
9224                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9225                        ainfo, intent, description, thumbnailInfo);
9226
9227                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9228                if (trimIdx >= 0) {
9229                    // If this would have caused a trim, then we'll abort because that
9230                    // means it would be added at the end of the list but then just removed.
9231                    return INVALID_TASK_ID;
9232                }
9233
9234                final int N = mRecentTasks.size();
9235                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9236                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9237                    tr.removedFromRecents();
9238                }
9239
9240                task.inRecents = true;
9241                mRecentTasks.add(task);
9242                r.task.stack.addTask(task, false, "addAppTask");
9243
9244                task.setLastThumbnailLocked(thumbnail);
9245                task.freeLastThumbnail();
9246
9247                return task.taskId;
9248            }
9249        } finally {
9250            Binder.restoreCallingIdentity(callingIdent);
9251        }
9252    }
9253
9254    @Override
9255    public Point getAppTaskThumbnailSize() {
9256        synchronized (this) {
9257            return new Point(mThumbnailWidth,  mThumbnailHeight);
9258        }
9259    }
9260
9261    @Override
9262    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9263        synchronized (this) {
9264            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9265            if (r != null) {
9266                r.setTaskDescription(td);
9267                r.task.updateTaskDescription();
9268            }
9269        }
9270    }
9271
9272    @Override
9273    public void setTaskResizeable(int taskId, int resizeableMode) {
9274        synchronized (this) {
9275            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9276                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9277            if (task == null) {
9278                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9279                return;
9280            }
9281            if (task.mResizeMode != resizeableMode) {
9282                task.mResizeMode = resizeableMode;
9283                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9284                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9285                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9286            }
9287        }
9288    }
9289
9290    @Override
9291    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9292        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9293        long ident = Binder.clearCallingIdentity();
9294        try {
9295            synchronized (this) {
9296                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9297                if (task == null) {
9298                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9299                    return;
9300                }
9301                int stackId = task.stack.mStackId;
9302                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9303                // in crop windows resize mode or if the task size is affected by the docked stack
9304                // changing size. No need to update configuration.
9305                if (bounds != null && task.inCropWindowsResizeMode()
9306                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9307                    mWindowManager.scrollTask(task.taskId, bounds);
9308                    return;
9309                }
9310
9311                // Place the task in the right stack if it isn't there already based on
9312                // the requested bounds.
9313                // The stack transition logic is:
9314                // - a null bounds on a freeform task moves that task to fullscreen
9315                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9316                //   that task to freeform
9317                // - otherwise the task is not moved
9318                if (!StackId.isTaskResizeAllowed(stackId)) {
9319                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9320                }
9321                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9322                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9323                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9324                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9325                }
9326                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9327                if (stackId != task.stack.mStackId) {
9328                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9329                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9330                    preserveWindow = false;
9331                }
9332
9333                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9334                        false /* deferResume */);
9335            }
9336        } finally {
9337            Binder.restoreCallingIdentity(ident);
9338        }
9339    }
9340
9341    @Override
9342    public Rect getTaskBounds(int taskId) {
9343        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9344        long ident = Binder.clearCallingIdentity();
9345        Rect rect = new Rect();
9346        try {
9347            synchronized (this) {
9348                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9349                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9350                if (task == null) {
9351                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9352                    return rect;
9353                }
9354                if (task.stack != null) {
9355                    // Return the bounds from window manager since it will be adjusted for various
9356                    // things like the presense of a docked stack for tasks that aren't resizeable.
9357                    mWindowManager.getTaskBounds(task.taskId, rect);
9358                } else {
9359                    // Task isn't in window manager yet since it isn't associated with a stack.
9360                    // Return the persist value from activity manager
9361                    if (task.mBounds != null) {
9362                        rect.set(task.mBounds);
9363                    } else if (task.mLastNonFullscreenBounds != null) {
9364                        rect.set(task.mLastNonFullscreenBounds);
9365                    }
9366                }
9367            }
9368        } finally {
9369            Binder.restoreCallingIdentity(ident);
9370        }
9371        return rect;
9372    }
9373
9374    @Override
9375    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9376        if (userId != UserHandle.getCallingUserId()) {
9377            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9378                    "getTaskDescriptionIcon");
9379        }
9380        final File passedIconFile = new File(filePath);
9381        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9382                passedIconFile.getName());
9383        if (!legitIconFile.getPath().equals(filePath)
9384                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9385            throw new IllegalArgumentException("Bad file path: " + filePath
9386                    + " passed for userId " + userId);
9387        }
9388        return mRecentTasks.getTaskDescriptionIcon(filePath);
9389    }
9390
9391    @Override
9392    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9393            throws RemoteException {
9394        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9395                opts.getCustomInPlaceResId() == 0) {
9396            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9397                    "with valid animation");
9398        }
9399        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9400        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9401                opts.getCustomInPlaceResId());
9402        mWindowManager.executeAppTransition();
9403    }
9404
9405    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9406            boolean removeFromRecents) {
9407        if (removeFromRecents) {
9408            mRecentTasks.remove(tr);
9409            tr.removedFromRecents();
9410        }
9411        ComponentName component = tr.getBaseIntent().getComponent();
9412        if (component == null) {
9413            Slog.w(TAG, "No component for base intent of task: " + tr);
9414            return;
9415        }
9416
9417        // Find any running services associated with this app and stop if needed.
9418        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9419
9420        if (!killProcess) {
9421            return;
9422        }
9423
9424        // Determine if the process(es) for this task should be killed.
9425        final String pkg = component.getPackageName();
9426        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9427        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9428        for (int i = 0; i < pmap.size(); i++) {
9429
9430            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9431            for (int j = 0; j < uids.size(); j++) {
9432                ProcessRecord proc = uids.valueAt(j);
9433                if (proc.userId != tr.userId) {
9434                    // Don't kill process for a different user.
9435                    continue;
9436                }
9437                if (proc == mHomeProcess) {
9438                    // Don't kill the home process along with tasks from the same package.
9439                    continue;
9440                }
9441                if (!proc.pkgList.containsKey(pkg)) {
9442                    // Don't kill process that is not associated with this task.
9443                    continue;
9444                }
9445
9446                for (int k = 0; k < proc.activities.size(); k++) {
9447                    TaskRecord otherTask = proc.activities.get(k).task;
9448                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9449                        // Don't kill process(es) that has an activity in a different task that is
9450                        // also in recents.
9451                        return;
9452                    }
9453                }
9454
9455                if (proc.foregroundServices) {
9456                    // Don't kill process(es) with foreground service.
9457                    return;
9458                }
9459
9460                // Add process to kill list.
9461                procsToKill.add(proc);
9462            }
9463        }
9464
9465        // Kill the running processes.
9466        for (int i = 0; i < procsToKill.size(); i++) {
9467            ProcessRecord pr = procsToKill.get(i);
9468            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9469                    && pr.curReceiver == null) {
9470                pr.kill("remove task", true);
9471            } else {
9472                // We delay killing processes that are not in the background or running a receiver.
9473                pr.waitingToKill = "remove task";
9474            }
9475        }
9476    }
9477
9478    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9479        // Remove all tasks with activities in the specified package from the list of recent tasks
9480        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9481            TaskRecord tr = mRecentTasks.get(i);
9482            if (tr.userId != userId) continue;
9483
9484            ComponentName cn = tr.intent.getComponent();
9485            if (cn != null && cn.getPackageName().equals(packageName)) {
9486                // If the package name matches, remove the task.
9487                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9488            }
9489        }
9490    }
9491
9492    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9493            int userId) {
9494
9495        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9496            TaskRecord tr = mRecentTasks.get(i);
9497            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9498                continue;
9499            }
9500
9501            ComponentName cn = tr.intent.getComponent();
9502            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9503                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9504            if (sameComponent) {
9505                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9506            }
9507        }
9508    }
9509
9510    /**
9511     * Removes the task with the specified task id.
9512     *
9513     * @param taskId Identifier of the task to be removed.
9514     * @param killProcess Kill any process associated with the task if possible.
9515     * @param removeFromRecents Whether to also remove the task from recents.
9516     * @return Returns true if the given task was found and removed.
9517     */
9518    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9519            boolean removeFromRecents) {
9520        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9521                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9522        if (tr != null) {
9523            tr.removeTaskActivitiesLocked();
9524            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9525            if (tr.isPersistable) {
9526                notifyTaskPersisterLocked(null, true);
9527            }
9528            return true;
9529        }
9530        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9531        return false;
9532    }
9533
9534    @Override
9535    public void removeStack(int stackId) {
9536        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9537        if (stackId == HOME_STACK_ID) {
9538            throw new IllegalArgumentException("Removing home stack is not allowed.");
9539        }
9540
9541        synchronized (this) {
9542            final long ident = Binder.clearCallingIdentity();
9543            try {
9544                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9545                if (stack == null) {
9546                    return;
9547                }
9548                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9549                for (int i = tasks.size() - 1; i >= 0; i--) {
9550                    removeTaskByIdLocked(
9551                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9552                }
9553            } finally {
9554                Binder.restoreCallingIdentity(ident);
9555            }
9556        }
9557    }
9558
9559    @Override
9560    public boolean removeTask(int taskId) {
9561        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9562        synchronized (this) {
9563            final long ident = Binder.clearCallingIdentity();
9564            try {
9565                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9566            } finally {
9567                Binder.restoreCallingIdentity(ident);
9568            }
9569        }
9570    }
9571
9572    /**
9573     * TODO: Add mController hook
9574     */
9575    @Override
9576    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9577        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9578
9579        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9580        synchronized(this) {
9581            moveTaskToFrontLocked(taskId, flags, bOptions);
9582        }
9583    }
9584
9585    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9586        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9587
9588        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9589                Binder.getCallingUid(), -1, -1, "Task to front")) {
9590            ActivityOptions.abort(options);
9591            return;
9592        }
9593        final long origId = Binder.clearCallingIdentity();
9594        try {
9595            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9596            if (task == null) {
9597                Slog.d(TAG, "Could not find task for id: "+ taskId);
9598                return;
9599            }
9600            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9601                mStackSupervisor.showLockTaskToast();
9602                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9603                return;
9604            }
9605            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9606            if (prev != null && prev.isRecentsActivity()) {
9607                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9608            }
9609            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9610                    false /* forceNonResizable */);
9611        } finally {
9612            Binder.restoreCallingIdentity(origId);
9613        }
9614        ActivityOptions.abort(options);
9615    }
9616
9617    /**
9618     * Moves an activity, and all of the other activities within the same task, to the bottom
9619     * of the history stack.  The activity's order within the task is unchanged.
9620     *
9621     * @param token A reference to the activity we wish to move
9622     * @param nonRoot If false then this only works if the activity is the root
9623     *                of a task; if true it will work for any activity in a task.
9624     * @return Returns true if the move completed, false if not.
9625     */
9626    @Override
9627    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9628        enforceNotIsolatedCaller("moveActivityTaskToBack");
9629        synchronized(this) {
9630            final long origId = Binder.clearCallingIdentity();
9631            try {
9632                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9633                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9634                if (task != null) {
9635                    if (mStackSupervisor.isLockedTask(task)) {
9636                        mStackSupervisor.showLockTaskToast();
9637                        return false;
9638                    }
9639                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9640                }
9641            } finally {
9642                Binder.restoreCallingIdentity(origId);
9643            }
9644        }
9645        return false;
9646    }
9647
9648    @Override
9649    public void moveTaskBackwards(int task) {
9650        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9651                "moveTaskBackwards()");
9652
9653        synchronized(this) {
9654            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9655                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9656                return;
9657            }
9658            final long origId = Binder.clearCallingIdentity();
9659            moveTaskBackwardsLocked(task);
9660            Binder.restoreCallingIdentity(origId);
9661        }
9662    }
9663
9664    private final void moveTaskBackwardsLocked(int task) {
9665        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9666    }
9667
9668    @Override
9669    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9670            IActivityContainerCallback callback) throws RemoteException {
9671        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9672        synchronized (this) {
9673            if (parentActivityToken == null) {
9674                throw new IllegalArgumentException("parent token must not be null");
9675            }
9676            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9677            if (r == null) {
9678                return null;
9679            }
9680            if (callback == null) {
9681                throw new IllegalArgumentException("callback must not be null");
9682            }
9683            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9684        }
9685    }
9686
9687    @Override
9688    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9689        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9690        synchronized (this) {
9691            mStackSupervisor.deleteActivityContainer(container);
9692        }
9693    }
9694
9695    @Override
9696    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9697        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9698        synchronized (this) {
9699            final int stackId = mStackSupervisor.getNextStackId();
9700            final ActivityStack stack =
9701                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9702            if (stack == null) {
9703                return null;
9704            }
9705            return stack.mActivityContainer;
9706        }
9707    }
9708
9709    @Override
9710    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9711        synchronized (this) {
9712            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9713            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9714                return stack.mActivityContainer.getDisplayId();
9715            }
9716            return Display.DEFAULT_DISPLAY;
9717        }
9718    }
9719
9720    @Override
9721    public int getActivityStackId(IBinder token) throws RemoteException {
9722        synchronized (this) {
9723            ActivityStack stack = ActivityRecord.getStackLocked(token);
9724            if (stack == null) {
9725                return INVALID_STACK_ID;
9726            }
9727            return stack.mStackId;
9728        }
9729    }
9730
9731    @Override
9732    public void exitFreeformMode(IBinder token) throws RemoteException {
9733        synchronized (this) {
9734            long ident = Binder.clearCallingIdentity();
9735            try {
9736                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9737                if (r == null) {
9738                    throw new IllegalArgumentException(
9739                            "exitFreeformMode: No activity record matching token=" + token);
9740                }
9741                final ActivityStack stack = r.getStackLocked(token);
9742                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9743                    throw new IllegalStateException(
9744                            "exitFreeformMode: You can only go fullscreen from freeform.");
9745                }
9746                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9747                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9748                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9749            } finally {
9750                Binder.restoreCallingIdentity(ident);
9751            }
9752        }
9753    }
9754
9755    @Override
9756    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9757        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9758        if (stackId == HOME_STACK_ID) {
9759            throw new IllegalArgumentException(
9760                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9761        }
9762        synchronized (this) {
9763            long ident = Binder.clearCallingIdentity();
9764            try {
9765                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9766                        + " to stackId=" + stackId + " toTop=" + toTop);
9767                if (stackId == DOCKED_STACK_ID) {
9768                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9769                            null /* initialBounds */);
9770                }
9771                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9772                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9773                if (result && stackId == DOCKED_STACK_ID) {
9774                    // If task moved to docked stack - show recents if needed.
9775                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9776                            "moveTaskToDockedStack");
9777                }
9778            } finally {
9779                Binder.restoreCallingIdentity(ident);
9780            }
9781        }
9782    }
9783
9784    @Override
9785    public void swapDockedAndFullscreenStack() throws RemoteException {
9786        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9787        synchronized (this) {
9788            long ident = Binder.clearCallingIdentity();
9789            try {
9790                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9791                        FULLSCREEN_WORKSPACE_STACK_ID);
9792                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9793                        : null;
9794                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9795                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9796                        : null;
9797                if (topTask == null || tasks == null || tasks.size() == 0) {
9798                    Slog.w(TAG,
9799                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9800                    return;
9801                }
9802
9803                // TODO: App transition
9804                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9805
9806                // Defer the resume so resume/pausing while moving stacks is dangerous.
9807                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9808                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9809                        ANIMATE, true /* deferResume */);
9810                final int size = tasks.size();
9811                for (int i = 0; i < size; i++) {
9812                    final int id = tasks.get(i).taskId;
9813                    if (id == topTask.taskId) {
9814                        continue;
9815                    }
9816                    mStackSupervisor.moveTaskToStackLocked(id,
9817                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9818                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9819                }
9820
9821                // Because we deferred the resume, to avoid conflicts with stack switches while
9822                // resuming, we need to do it after all the tasks are moved.
9823                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9824                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9825
9826                mWindowManager.executeAppTransition();
9827            } finally {
9828                Binder.restoreCallingIdentity(ident);
9829            }
9830        }
9831    }
9832
9833    /**
9834     * Moves the input task to the docked stack.
9835     *
9836     * @param taskId Id of task to move.
9837     * @param createMode The mode the docked stack should be created in if it doesn't exist
9838     *                   already. See
9839     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9840     *                   and
9841     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9842     * @param toTop If the task and stack should be moved to the top.
9843     * @param animate Whether we should play an animation for the moving the task
9844     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9845     *                      docked stack. Pass {@code null} to use default bounds.
9846     */
9847    @Override
9848    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9849            Rect initialBounds, boolean moveHomeStackFront) {
9850        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9851        synchronized (this) {
9852            long ident = Binder.clearCallingIdentity();
9853            try {
9854                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9855                        + " to createMode=" + createMode + " toTop=" + toTop);
9856                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9857                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9858                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9859                        animate, DEFER_RESUME);
9860                if (moved) {
9861                    if (moveHomeStackFront) {
9862                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9863                    }
9864                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9865                }
9866                return moved;
9867            } finally {
9868                Binder.restoreCallingIdentity(ident);
9869            }
9870        }
9871    }
9872
9873    /**
9874     * Moves the top activity in the input stackId to the pinned stack.
9875     *
9876     * @param stackId Id of stack to move the top activity to pinned stack.
9877     * @param bounds Bounds to use for pinned stack.
9878     *
9879     * @return True if the top activity of the input stack was successfully moved to the pinned
9880     *          stack.
9881     */
9882    @Override
9883    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9884        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9885        synchronized (this) {
9886            if (!mSupportsPictureInPicture) {
9887                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9888                        + "Device doesn't support picture-in-pciture mode");
9889            }
9890
9891            long ident = Binder.clearCallingIdentity();
9892            try {
9893                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9894            } finally {
9895                Binder.restoreCallingIdentity(ident);
9896            }
9897        }
9898    }
9899
9900    @Override
9901    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9902            boolean preserveWindows, boolean animate, int animationDuration) {
9903        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9904        long ident = Binder.clearCallingIdentity();
9905        try {
9906            synchronized (this) {
9907                if (animate) {
9908                    if (stackId == PINNED_STACK_ID) {
9909                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9910                    } else {
9911                        throw new IllegalArgumentException("Stack: " + stackId
9912                                + " doesn't support animated resize.");
9913                    }
9914                } else {
9915                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9916                            null /* tempTaskInsetBounds */, preserveWindows,
9917                            allowResizeInDockedMode, !DEFER_RESUME);
9918                }
9919            }
9920        } finally {
9921            Binder.restoreCallingIdentity(ident);
9922        }
9923    }
9924
9925    @Override
9926    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9927            Rect tempDockedTaskInsetBounds,
9928            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9929        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9930                "resizeDockedStack()");
9931        long ident = Binder.clearCallingIdentity();
9932        try {
9933            synchronized (this) {
9934                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9935                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9936                        PRESERVE_WINDOWS);
9937            }
9938        } finally {
9939            Binder.restoreCallingIdentity(ident);
9940        }
9941    }
9942
9943    @Override
9944    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9945        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9946                "resizePinnedStack()");
9947        final long ident = Binder.clearCallingIdentity();
9948        try {
9949            synchronized (this) {
9950                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9951            }
9952        } finally {
9953            Binder.restoreCallingIdentity(ident);
9954        }
9955    }
9956
9957    @Override
9958    public void positionTaskInStack(int taskId, int stackId, int position) {
9959        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9960        if (stackId == HOME_STACK_ID) {
9961            throw new IllegalArgumentException(
9962                    "positionTaskInStack: Attempt to change the position of task "
9963                    + taskId + " in/to home stack");
9964        }
9965        synchronized (this) {
9966            long ident = Binder.clearCallingIdentity();
9967            try {
9968                if (DEBUG_STACK) Slog.d(TAG_STACK,
9969                        "positionTaskInStack: positioning task=" + taskId
9970                        + " in stackId=" + stackId + " at position=" + position);
9971                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9972            } finally {
9973                Binder.restoreCallingIdentity(ident);
9974            }
9975        }
9976    }
9977
9978    @Override
9979    public List<StackInfo> getAllStackInfos() {
9980        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9981        long ident = Binder.clearCallingIdentity();
9982        try {
9983            synchronized (this) {
9984                return mStackSupervisor.getAllStackInfosLocked();
9985            }
9986        } finally {
9987            Binder.restoreCallingIdentity(ident);
9988        }
9989    }
9990
9991    @Override
9992    public StackInfo getStackInfo(int stackId) {
9993        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9994        long ident = Binder.clearCallingIdentity();
9995        try {
9996            synchronized (this) {
9997                return mStackSupervisor.getStackInfoLocked(stackId);
9998            }
9999        } finally {
10000            Binder.restoreCallingIdentity(ident);
10001        }
10002    }
10003
10004    @Override
10005    public boolean isInHomeStack(int taskId) {
10006        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10007        long ident = Binder.clearCallingIdentity();
10008        try {
10009            synchronized (this) {
10010                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10011                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10012                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10013            }
10014        } finally {
10015            Binder.restoreCallingIdentity(ident);
10016        }
10017    }
10018
10019    @Override
10020    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10021        synchronized(this) {
10022            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10023        }
10024    }
10025
10026    @Override
10027    public void updateDeviceOwner(String packageName) {
10028        final int callingUid = Binder.getCallingUid();
10029        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10030            throw new SecurityException("updateDeviceOwner called from non-system process");
10031        }
10032        synchronized (this) {
10033            mDeviceOwnerName = packageName;
10034        }
10035    }
10036
10037    @Override
10038    public void updateLockTaskPackages(int userId, String[] packages) {
10039        final int callingUid = Binder.getCallingUid();
10040        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10041            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10042                    "updateLockTaskPackages()");
10043        }
10044        synchronized (this) {
10045            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10046                    Arrays.toString(packages));
10047            mLockTaskPackages.put(userId, packages);
10048            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10049        }
10050    }
10051
10052
10053    void startLockTaskModeLocked(TaskRecord task) {
10054        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10055        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10056            return;
10057        }
10058
10059        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10060        // is initiated by system after the pinning request was shown and locked mode is initiated
10061        // by an authorized app directly
10062        final int callingUid = Binder.getCallingUid();
10063        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            if (!isSystemInitiated) {
10067                task.mLockTaskUid = callingUid;
10068                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10069                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10070                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10071                    StatusBarManagerInternal statusBarManager =
10072                            LocalServices.getService(StatusBarManagerInternal.class);
10073                    if (statusBarManager != null) {
10074                        statusBarManager.showScreenPinningRequest(task.taskId);
10075                    }
10076                    return;
10077                }
10078
10079                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10080                if (stack == null || task != stack.topTask()) {
10081                    throw new IllegalArgumentException("Invalid task, not in foreground");
10082                }
10083            }
10084            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10085                    "Locking fully");
10086            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10087                    ActivityManager.LOCK_TASK_MODE_PINNED :
10088                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10089                    "startLockTask", true);
10090        } finally {
10091            Binder.restoreCallingIdentity(ident);
10092        }
10093    }
10094
10095    @Override
10096    public void startLockTaskMode(int taskId) {
10097        synchronized (this) {
10098            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10099            if (task != null) {
10100                startLockTaskModeLocked(task);
10101            }
10102        }
10103    }
10104
10105    @Override
10106    public void startLockTaskMode(IBinder token) {
10107        synchronized (this) {
10108            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10109            if (r == null) {
10110                return;
10111            }
10112            final TaskRecord task = r.task;
10113            if (task != null) {
10114                startLockTaskModeLocked(task);
10115            }
10116        }
10117    }
10118
10119    @Override
10120    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10121        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10122        // This makes inner call to look as if it was initiated by system.
10123        long ident = Binder.clearCallingIdentity();
10124        try {
10125            synchronized (this) {
10126                startLockTaskMode(taskId);
10127            }
10128        } finally {
10129            Binder.restoreCallingIdentity(ident);
10130        }
10131    }
10132
10133    @Override
10134    public void stopLockTaskMode() {
10135        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10136        if (lockTask == null) {
10137            // Our work here is done.
10138            return;
10139        }
10140
10141        final int callingUid = Binder.getCallingUid();
10142        final int lockTaskUid = lockTask.mLockTaskUid;
10143        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10144        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10145            // Done.
10146            return;
10147        } else {
10148            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10149            // It is possible lockTaskMode was started by the system process because
10150            // android:lockTaskMode is set to a locking value in the application manifest
10151            // instead of the app calling startLockTaskMode. In this case
10152            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10153            // {@link TaskRecord.effectiveUid} instead. Also caller with
10154            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10155            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10156                    && callingUid != lockTaskUid
10157                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10158                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10159                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10160            }
10161        }
10162        long ident = Binder.clearCallingIdentity();
10163        try {
10164            Log.d(TAG, "stopLockTaskMode");
10165            // Stop lock task
10166            synchronized (this) {
10167                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10168                        "stopLockTask", true);
10169            }
10170            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10171            if (tm != null) {
10172                tm.showInCallScreen(false);
10173            }
10174        } finally {
10175            Binder.restoreCallingIdentity(ident);
10176        }
10177    }
10178
10179    /**
10180     * This API should be called by SystemUI only when user perform certain action to dismiss
10181     * lock task mode. We should only dismiss pinned lock task mode in this case.
10182     */
10183    @Override
10184    public void stopSystemLockTaskMode() throws RemoteException {
10185        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10186            stopLockTaskMode();
10187        } else {
10188            mStackSupervisor.showLockTaskToast();
10189        }
10190    }
10191
10192    @Override
10193    public boolean isInLockTaskMode() {
10194        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10195    }
10196
10197    @Override
10198    public int getLockTaskModeState() {
10199        synchronized (this) {
10200            return mStackSupervisor.getLockTaskModeState();
10201        }
10202    }
10203
10204    @Override
10205    public void showLockTaskEscapeMessage(IBinder token) {
10206        synchronized (this) {
10207            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10208            if (r == null) {
10209                return;
10210            }
10211            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10212        }
10213    }
10214
10215    // =========================================================
10216    // CONTENT PROVIDERS
10217    // =========================================================
10218
10219    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10220        List<ProviderInfo> providers = null;
10221        try {
10222            providers = AppGlobals.getPackageManager()
10223                    .queryContentProviders(app.processName, app.uid,
10224                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10225                                    | MATCH_DEBUG_TRIAGED_MISSING)
10226                    .getList();
10227        } catch (RemoteException ex) {
10228        }
10229        if (DEBUG_MU) Slog.v(TAG_MU,
10230                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10231        int userId = app.userId;
10232        if (providers != null) {
10233            int N = providers.size();
10234            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10235            for (int i=0; i<N; i++) {
10236                // TODO: keep logic in sync with installEncryptionUnawareProviders
10237                ProviderInfo cpi =
10238                    (ProviderInfo)providers.get(i);
10239                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10240                        cpi.name, cpi.flags);
10241                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10242                    // This is a singleton provider, but a user besides the
10243                    // default user is asking to initialize a process it runs
10244                    // in...  well, no, it doesn't actually run in this process,
10245                    // it runs in the process of the default user.  Get rid of it.
10246                    providers.remove(i);
10247                    N--;
10248                    i--;
10249                    continue;
10250                }
10251
10252                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10253                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10254                if (cpr == null) {
10255                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10256                    mProviderMap.putProviderByClass(comp, cpr);
10257                }
10258                if (DEBUG_MU) Slog.v(TAG_MU,
10259                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10260                app.pubProviders.put(cpi.name, cpr);
10261                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10262                    // Don't add this if it is a platform component that is marked
10263                    // to run in multiple processes, because this is actually
10264                    // part of the framework so doesn't make sense to track as a
10265                    // separate apk in the process.
10266                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10267                            mProcessStats);
10268                }
10269                notifyPackageUse(cpi.applicationInfo.packageName,
10270                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10271            }
10272        }
10273        return providers;
10274    }
10275
10276    /**
10277     * Check if {@link ProcessRecord} has a possible chance at accessing the
10278     * given {@link ProviderInfo}. Final permission checking is always done
10279     * in {@link ContentProvider}.
10280     */
10281    private final String checkContentProviderPermissionLocked(
10282            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10283        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10284        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10285        boolean checkedGrants = false;
10286        if (checkUser) {
10287            // Looking for cross-user grants before enforcing the typical cross-users permissions
10288            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10289            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10290                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10291                    return null;
10292                }
10293                checkedGrants = true;
10294            }
10295            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10296                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10297            if (userId != tmpTargetUserId) {
10298                // When we actually went to determine the final targer user ID, this ended
10299                // up different than our initial check for the authority.  This is because
10300                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10301                // SELF.  So we need to re-check the grants again.
10302                checkedGrants = false;
10303            }
10304        }
10305        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10306                cpi.applicationInfo.uid, cpi.exported)
10307                == PackageManager.PERMISSION_GRANTED) {
10308            return null;
10309        }
10310        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10311                cpi.applicationInfo.uid, cpi.exported)
10312                == PackageManager.PERMISSION_GRANTED) {
10313            return null;
10314        }
10315
10316        PathPermission[] pps = cpi.pathPermissions;
10317        if (pps != null) {
10318            int i = pps.length;
10319            while (i > 0) {
10320                i--;
10321                PathPermission pp = pps[i];
10322                String pprperm = pp.getReadPermission();
10323                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10324                        cpi.applicationInfo.uid, cpi.exported)
10325                        == PackageManager.PERMISSION_GRANTED) {
10326                    return null;
10327                }
10328                String ppwperm = pp.getWritePermission();
10329                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10330                        cpi.applicationInfo.uid, cpi.exported)
10331                        == PackageManager.PERMISSION_GRANTED) {
10332                    return null;
10333                }
10334            }
10335        }
10336        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10337            return null;
10338        }
10339
10340        String msg;
10341        if (!cpi.exported) {
10342            msg = "Permission Denial: opening provider " + cpi.name
10343                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10344                    + ", uid=" + callingUid + ") that is not exported from uid "
10345                    + cpi.applicationInfo.uid;
10346        } else {
10347            msg = "Permission Denial: opening provider " + cpi.name
10348                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10349                    + ", uid=" + callingUid + ") requires "
10350                    + cpi.readPermission + " or " + cpi.writePermission;
10351        }
10352        Slog.w(TAG, msg);
10353        return msg;
10354    }
10355
10356    /**
10357     * Returns if the ContentProvider has granted a uri to callingUid
10358     */
10359    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10360        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10361        if (perms != null) {
10362            for (int i=perms.size()-1; i>=0; i--) {
10363                GrantUri grantUri = perms.keyAt(i);
10364                if (grantUri.sourceUserId == userId || !checkUser) {
10365                    if (matchesProvider(grantUri.uri, cpi)) {
10366                        return true;
10367                    }
10368                }
10369            }
10370        }
10371        return false;
10372    }
10373
10374    /**
10375     * Returns true if the uri authority is one of the authorities specified in the provider.
10376     */
10377    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10378        String uriAuth = uri.getAuthority();
10379        String cpiAuth = cpi.authority;
10380        if (cpiAuth.indexOf(';') == -1) {
10381            return cpiAuth.equals(uriAuth);
10382        }
10383        String[] cpiAuths = cpiAuth.split(";");
10384        int length = cpiAuths.length;
10385        for (int i = 0; i < length; i++) {
10386            if (cpiAuths[i].equals(uriAuth)) return true;
10387        }
10388        return false;
10389    }
10390
10391    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10392            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10393        if (r != null) {
10394            for (int i=0; i<r.conProviders.size(); i++) {
10395                ContentProviderConnection conn = r.conProviders.get(i);
10396                if (conn.provider == cpr) {
10397                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10398                            "Adding provider requested by "
10399                            + r.processName + " from process "
10400                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10401                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10402                    if (stable) {
10403                        conn.stableCount++;
10404                        conn.numStableIncs++;
10405                    } else {
10406                        conn.unstableCount++;
10407                        conn.numUnstableIncs++;
10408                    }
10409                    return conn;
10410                }
10411            }
10412            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10413            if (stable) {
10414                conn.stableCount = 1;
10415                conn.numStableIncs = 1;
10416            } else {
10417                conn.unstableCount = 1;
10418                conn.numUnstableIncs = 1;
10419            }
10420            cpr.connections.add(conn);
10421            r.conProviders.add(conn);
10422            startAssociationLocked(r.uid, r.processName, r.curProcState,
10423                    cpr.uid, cpr.name, cpr.info.processName);
10424            return conn;
10425        }
10426        cpr.addExternalProcessHandleLocked(externalProcessToken);
10427        return null;
10428    }
10429
10430    boolean decProviderCountLocked(ContentProviderConnection conn,
10431            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10432        if (conn != null) {
10433            cpr = conn.provider;
10434            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10435                    "Removing provider requested by "
10436                    + conn.client.processName + " from process "
10437                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10438                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10439            if (stable) {
10440                conn.stableCount--;
10441            } else {
10442                conn.unstableCount--;
10443            }
10444            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10445                cpr.connections.remove(conn);
10446                conn.client.conProviders.remove(conn);
10447                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10448                    // The client is more important than last activity -- note the time this
10449                    // is happening, so we keep the old provider process around a bit as last
10450                    // activity to avoid thrashing it.
10451                    if (cpr.proc != null) {
10452                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10453                    }
10454                }
10455                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10456                return true;
10457            }
10458            return false;
10459        }
10460        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10461        return false;
10462    }
10463
10464    private void checkTime(long startTime, String where) {
10465        long now = SystemClock.uptimeMillis();
10466        if ((now-startTime) > 50) {
10467            // If we are taking more than 50ms, log about it.
10468            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10469        }
10470    }
10471
10472    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10473            String name, IBinder token, boolean stable, int userId) {
10474        ContentProviderRecord cpr;
10475        ContentProviderConnection conn = null;
10476        ProviderInfo cpi = null;
10477
10478        synchronized(this) {
10479            long startTime = SystemClock.uptimeMillis();
10480
10481            ProcessRecord r = null;
10482            if (caller != null) {
10483                r = getRecordForAppLocked(caller);
10484                if (r == null) {
10485                    throw new SecurityException(
10486                            "Unable to find app for caller " + caller
10487                          + " (pid=" + Binder.getCallingPid()
10488                          + ") when getting content provider " + name);
10489                }
10490            }
10491
10492            boolean checkCrossUser = true;
10493
10494            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10495
10496            // First check if this content provider has been published...
10497            cpr = mProviderMap.getProviderByName(name, userId);
10498            // If that didn't work, check if it exists for user 0 and then
10499            // verify that it's a singleton provider before using it.
10500            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10501                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10502                if (cpr != null) {
10503                    cpi = cpr.info;
10504                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10505                            cpi.name, cpi.flags)
10506                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10507                        userId = UserHandle.USER_SYSTEM;
10508                        checkCrossUser = false;
10509                    } else {
10510                        cpr = null;
10511                        cpi = null;
10512                    }
10513                }
10514            }
10515
10516            boolean providerRunning = cpr != null;
10517            if (providerRunning) {
10518                cpi = cpr.info;
10519                String msg;
10520                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10521                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10522                        != null) {
10523                    throw new SecurityException(msg);
10524                }
10525                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10526
10527                if (r != null && cpr.canRunHere(r)) {
10528                    // This provider has been published or is in the process
10529                    // of being published...  but it is also allowed to run
10530                    // in the caller's process, so don't make a connection
10531                    // and just let the caller instantiate its own instance.
10532                    ContentProviderHolder holder = cpr.newHolder(null);
10533                    // don't give caller the provider object, it needs
10534                    // to make its own.
10535                    holder.provider = null;
10536                    return holder;
10537                }
10538
10539                final long origId = Binder.clearCallingIdentity();
10540
10541                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10542
10543                // In this case the provider instance already exists, so we can
10544                // return it right away.
10545                conn = incProviderCountLocked(r, cpr, token, stable);
10546                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10547                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10548                        // If this is a perceptible app accessing the provider,
10549                        // make sure to count it as being accessed and thus
10550                        // back up on the LRU list.  This is good because
10551                        // content providers are often expensive to start.
10552                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10553                        updateLruProcessLocked(cpr.proc, false, null);
10554                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10555                    }
10556                }
10557
10558                if (cpr.proc != null) {
10559                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10560                    boolean success = updateOomAdjLocked(cpr.proc);
10561                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10562                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10563                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10564                    // NOTE: there is still a race here where a signal could be
10565                    // pending on the process even though we managed to update its
10566                    // adj level.  Not sure what to do about this, but at least
10567                    // the race is now smaller.
10568                    if (!success) {
10569                        // Uh oh...  it looks like the provider's process
10570                        // has been killed on us.  We need to wait for a new
10571                        // process to be started, and make sure its death
10572                        // doesn't kill our process.
10573                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10574                                + " is crashing; detaching " + r);
10575                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10576                        checkTime(startTime, "getContentProviderImpl: before appDied");
10577                        appDiedLocked(cpr.proc);
10578                        checkTime(startTime, "getContentProviderImpl: after appDied");
10579                        if (!lastRef) {
10580                            // This wasn't the last ref our process had on
10581                            // the provider...  we have now been killed, bail.
10582                            return null;
10583                        }
10584                        providerRunning = false;
10585                        conn = null;
10586                    }
10587                }
10588
10589                Binder.restoreCallingIdentity(origId);
10590            }
10591
10592            if (!providerRunning) {
10593                try {
10594                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10595                    cpi = AppGlobals.getPackageManager().
10596                        resolveContentProvider(name,
10597                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10598                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10599                } catch (RemoteException ex) {
10600                }
10601                if (cpi == null) {
10602                    return null;
10603                }
10604                // If the provider is a singleton AND
10605                // (it's a call within the same user || the provider is a
10606                // privileged app)
10607                // Then allow connecting to the singleton provider
10608                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10609                        cpi.name, cpi.flags)
10610                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10611                if (singleton) {
10612                    userId = UserHandle.USER_SYSTEM;
10613                }
10614                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10615                checkTime(startTime, "getContentProviderImpl: got app info for user");
10616
10617                String msg;
10618                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10619                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10620                        != null) {
10621                    throw new SecurityException(msg);
10622                }
10623                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10624
10625                if (!mProcessesReady
10626                        && !cpi.processName.equals("system")) {
10627                    // If this content provider does not run in the system
10628                    // process, and the system is not yet ready to run other
10629                    // processes, then fail fast instead of hanging.
10630                    throw new IllegalArgumentException(
10631                            "Attempt to launch content provider before system ready");
10632                }
10633
10634                // Make sure that the user who owns this provider is running.  If not,
10635                // we don't want to allow it to run.
10636                if (!mUserController.isUserRunningLocked(userId, 0)) {
10637                    Slog.w(TAG, "Unable to launch app "
10638                            + cpi.applicationInfo.packageName + "/"
10639                            + cpi.applicationInfo.uid + " for provider "
10640                            + name + ": user " + userId + " is stopped");
10641                    return null;
10642                }
10643
10644                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10645                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10646                cpr = mProviderMap.getProviderByClass(comp, userId);
10647                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10648                final boolean firstClass = cpr == null;
10649                if (firstClass) {
10650                    final long ident = Binder.clearCallingIdentity();
10651
10652                    // If permissions need a review before any of the app components can run,
10653                    // we return no provider and launch a review activity if the calling app
10654                    // is in the foreground.
10655                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10656                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10657                            return null;
10658                        }
10659                    }
10660
10661                    try {
10662                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10663                        ApplicationInfo ai =
10664                            AppGlobals.getPackageManager().
10665                                getApplicationInfo(
10666                                        cpi.applicationInfo.packageName,
10667                                        STOCK_PM_FLAGS, userId);
10668                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10669                        if (ai == null) {
10670                            Slog.w(TAG, "No package info for content provider "
10671                                    + cpi.name);
10672                            return null;
10673                        }
10674                        ai = getAppInfoForUser(ai, userId);
10675                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10676                    } catch (RemoteException ex) {
10677                        // pm is in same process, this will never happen.
10678                    } finally {
10679                        Binder.restoreCallingIdentity(ident);
10680                    }
10681                }
10682
10683                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10684
10685                if (r != null && cpr.canRunHere(r)) {
10686                    // If this is a multiprocess provider, then just return its
10687                    // info and allow the caller to instantiate it.  Only do
10688                    // this if the provider is the same user as the caller's
10689                    // process, or can run as root (so can be in any process).
10690                    return cpr.newHolder(null);
10691                }
10692
10693                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10694                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10695                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10696
10697                // This is single process, and our app is now connecting to it.
10698                // See if we are already in the process of launching this
10699                // provider.
10700                final int N = mLaunchingProviders.size();
10701                int i;
10702                for (i = 0; i < N; i++) {
10703                    if (mLaunchingProviders.get(i) == cpr) {
10704                        break;
10705                    }
10706                }
10707
10708                // If the provider is not already being launched, then get it
10709                // started.
10710                if (i >= N) {
10711                    final long origId = Binder.clearCallingIdentity();
10712
10713                    try {
10714                        // Content provider is now in use, its package can't be stopped.
10715                        try {
10716                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10717                            AppGlobals.getPackageManager().setPackageStoppedState(
10718                                    cpr.appInfo.packageName, false, userId);
10719                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10720                        } catch (RemoteException e) {
10721                        } catch (IllegalArgumentException e) {
10722                            Slog.w(TAG, "Failed trying to unstop package "
10723                                    + cpr.appInfo.packageName + ": " + e);
10724                        }
10725
10726                        // Use existing process if already started
10727                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10728                        ProcessRecord proc = getProcessRecordLocked(
10729                                cpi.processName, cpr.appInfo.uid, false);
10730                        if (proc != null && proc.thread != null) {
10731                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10732                                    "Installing in existing process " + proc);
10733                            if (!proc.pubProviders.containsKey(cpi.name)) {
10734                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10735                                proc.pubProviders.put(cpi.name, cpr);
10736                                try {
10737                                    proc.thread.scheduleInstallProvider(cpi);
10738                                } catch (RemoteException e) {
10739                                }
10740                            }
10741                        } else {
10742                            checkTime(startTime, "getContentProviderImpl: before start process");
10743                            proc = startProcessLocked(cpi.processName,
10744                                    cpr.appInfo, false, 0, "content provider",
10745                                    new ComponentName(cpi.applicationInfo.packageName,
10746                                            cpi.name), false, false, false);
10747                            checkTime(startTime, "getContentProviderImpl: after start process");
10748                            if (proc == null) {
10749                                Slog.w(TAG, "Unable to launch app "
10750                                        + cpi.applicationInfo.packageName + "/"
10751                                        + cpi.applicationInfo.uid + " for provider "
10752                                        + name + ": process is bad");
10753                                return null;
10754                            }
10755                        }
10756                        cpr.launchingApp = proc;
10757                        mLaunchingProviders.add(cpr);
10758                    } finally {
10759                        Binder.restoreCallingIdentity(origId);
10760                    }
10761                }
10762
10763                checkTime(startTime, "getContentProviderImpl: updating data structures");
10764
10765                // Make sure the provider is published (the same provider class
10766                // may be published under multiple names).
10767                if (firstClass) {
10768                    mProviderMap.putProviderByClass(comp, cpr);
10769                }
10770
10771                mProviderMap.putProviderByName(name, cpr);
10772                conn = incProviderCountLocked(r, cpr, token, stable);
10773                if (conn != null) {
10774                    conn.waiting = true;
10775                }
10776            }
10777            checkTime(startTime, "getContentProviderImpl: done!");
10778        }
10779
10780        // Wait for the provider to be published...
10781        synchronized (cpr) {
10782            while (cpr.provider == null) {
10783                if (cpr.launchingApp == null) {
10784                    Slog.w(TAG, "Unable to launch app "
10785                            + cpi.applicationInfo.packageName + "/"
10786                            + cpi.applicationInfo.uid + " for provider "
10787                            + name + ": launching app became null");
10788                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10789                            UserHandle.getUserId(cpi.applicationInfo.uid),
10790                            cpi.applicationInfo.packageName,
10791                            cpi.applicationInfo.uid, name);
10792                    return null;
10793                }
10794                try {
10795                    if (DEBUG_MU) Slog.v(TAG_MU,
10796                            "Waiting to start provider " + cpr
10797                            + " launchingApp=" + cpr.launchingApp);
10798                    if (conn != null) {
10799                        conn.waiting = true;
10800                    }
10801                    cpr.wait();
10802                } catch (InterruptedException ex) {
10803                } finally {
10804                    if (conn != null) {
10805                        conn.waiting = false;
10806                    }
10807                }
10808            }
10809        }
10810        return cpr != null ? cpr.newHolder(conn) : null;
10811    }
10812
10813    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10814            ProcessRecord r, final int userId) {
10815        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10816                cpi.packageName, userId)) {
10817
10818            final boolean callerForeground = r == null || r.setSchedGroup
10819                    != ProcessList.SCHED_GROUP_BACKGROUND;
10820
10821            // Show a permission review UI only for starting from a foreground app
10822            if (!callerForeground) {
10823                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10824                        + cpi.packageName + " requires a permissions review");
10825                return false;
10826            }
10827
10828            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10829            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10830                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10831            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10832
10833            if (DEBUG_PERMISSIONS_REVIEW) {
10834                Slog.i(TAG, "u" + userId + " Launching permission review "
10835                        + "for package " + cpi.packageName);
10836            }
10837
10838            final UserHandle userHandle = new UserHandle(userId);
10839            mHandler.post(new Runnable() {
10840                @Override
10841                public void run() {
10842                    mContext.startActivityAsUser(intent, userHandle);
10843                }
10844            });
10845
10846            return false;
10847        }
10848
10849        return true;
10850    }
10851
10852    PackageManagerInternal getPackageManagerInternalLocked() {
10853        if (mPackageManagerInt == null) {
10854            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10855        }
10856        return mPackageManagerInt;
10857    }
10858
10859    @Override
10860    public final ContentProviderHolder getContentProvider(
10861            IApplicationThread caller, String name, int userId, boolean stable) {
10862        enforceNotIsolatedCaller("getContentProvider");
10863        if (caller == null) {
10864            String msg = "null IApplicationThread when getting content provider "
10865                    + name;
10866            Slog.w(TAG, msg);
10867            throw new SecurityException(msg);
10868        }
10869        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10870        // with cross-user grant.
10871        return getContentProviderImpl(caller, name, null, stable, userId);
10872    }
10873
10874    public ContentProviderHolder getContentProviderExternal(
10875            String name, int userId, IBinder token) {
10876        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10877            "Do not have permission in call getContentProviderExternal()");
10878        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10879                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10880        return getContentProviderExternalUnchecked(name, token, userId);
10881    }
10882
10883    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10884            IBinder token, int userId) {
10885        return getContentProviderImpl(null, name, token, true, userId);
10886    }
10887
10888    /**
10889     * Drop a content provider from a ProcessRecord's bookkeeping
10890     */
10891    public void removeContentProvider(IBinder connection, boolean stable) {
10892        enforceNotIsolatedCaller("removeContentProvider");
10893        long ident = Binder.clearCallingIdentity();
10894        try {
10895            synchronized (this) {
10896                ContentProviderConnection conn;
10897                try {
10898                    conn = (ContentProviderConnection)connection;
10899                } catch (ClassCastException e) {
10900                    String msg ="removeContentProvider: " + connection
10901                            + " not a ContentProviderConnection";
10902                    Slog.w(TAG, msg);
10903                    throw new IllegalArgumentException(msg);
10904                }
10905                if (conn == null) {
10906                    throw new NullPointerException("connection is null");
10907                }
10908                if (decProviderCountLocked(conn, null, null, stable)) {
10909                    updateOomAdjLocked();
10910                }
10911            }
10912        } finally {
10913            Binder.restoreCallingIdentity(ident);
10914        }
10915    }
10916
10917    public void removeContentProviderExternal(String name, IBinder token) {
10918        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10919            "Do not have permission in call removeContentProviderExternal()");
10920        int userId = UserHandle.getCallingUserId();
10921        long ident = Binder.clearCallingIdentity();
10922        try {
10923            removeContentProviderExternalUnchecked(name, token, userId);
10924        } finally {
10925            Binder.restoreCallingIdentity(ident);
10926        }
10927    }
10928
10929    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10930        synchronized (this) {
10931            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10932            if(cpr == null) {
10933                //remove from mProvidersByClass
10934                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10935                return;
10936            }
10937
10938            //update content provider record entry info
10939            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10940            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10941            if (localCpr.hasExternalProcessHandles()) {
10942                if (localCpr.removeExternalProcessHandleLocked(token)) {
10943                    updateOomAdjLocked();
10944                } else {
10945                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10946                            + " with no external reference for token: "
10947                            + token + ".");
10948                }
10949            } else {
10950                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10951                        + " with no external references.");
10952            }
10953        }
10954    }
10955
10956    public final void publishContentProviders(IApplicationThread caller,
10957            List<ContentProviderHolder> providers) {
10958        if (providers == null) {
10959            return;
10960        }
10961
10962        enforceNotIsolatedCaller("publishContentProviders");
10963        synchronized (this) {
10964            final ProcessRecord r = getRecordForAppLocked(caller);
10965            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10966            if (r == null) {
10967                throw new SecurityException(
10968                        "Unable to find app for caller " + caller
10969                      + " (pid=" + Binder.getCallingPid()
10970                      + ") when publishing content providers");
10971            }
10972
10973            final long origId = Binder.clearCallingIdentity();
10974
10975            final int N = providers.size();
10976            for (int i = 0; i < N; i++) {
10977                ContentProviderHolder src = providers.get(i);
10978                if (src == null || src.info == null || src.provider == null) {
10979                    continue;
10980                }
10981                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10982                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10983                if (dst != null) {
10984                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10985                    mProviderMap.putProviderByClass(comp, dst);
10986                    String names[] = dst.info.authority.split(";");
10987                    for (int j = 0; j < names.length; j++) {
10988                        mProviderMap.putProviderByName(names[j], dst);
10989                    }
10990
10991                    int launchingCount = mLaunchingProviders.size();
10992                    int j;
10993                    boolean wasInLaunchingProviders = false;
10994                    for (j = 0; j < launchingCount; j++) {
10995                        if (mLaunchingProviders.get(j) == dst) {
10996                            mLaunchingProviders.remove(j);
10997                            wasInLaunchingProviders = true;
10998                            j--;
10999                            launchingCount--;
11000                        }
11001                    }
11002                    if (wasInLaunchingProviders) {
11003                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11004                    }
11005                    synchronized (dst) {
11006                        dst.provider = src.provider;
11007                        dst.proc = r;
11008                        dst.notifyAll();
11009                    }
11010                    updateOomAdjLocked(r);
11011                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11012                            src.info.authority);
11013                }
11014            }
11015
11016            Binder.restoreCallingIdentity(origId);
11017        }
11018    }
11019
11020    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11021        ContentProviderConnection conn;
11022        try {
11023            conn = (ContentProviderConnection)connection;
11024        } catch (ClassCastException e) {
11025            String msg ="refContentProvider: " + connection
11026                    + " not a ContentProviderConnection";
11027            Slog.w(TAG, msg);
11028            throw new IllegalArgumentException(msg);
11029        }
11030        if (conn == null) {
11031            throw new NullPointerException("connection is null");
11032        }
11033
11034        synchronized (this) {
11035            if (stable > 0) {
11036                conn.numStableIncs += stable;
11037            }
11038            stable = conn.stableCount + stable;
11039            if (stable < 0) {
11040                throw new IllegalStateException("stableCount < 0: " + stable);
11041            }
11042
11043            if (unstable > 0) {
11044                conn.numUnstableIncs += unstable;
11045            }
11046            unstable = conn.unstableCount + unstable;
11047            if (unstable < 0) {
11048                throw new IllegalStateException("unstableCount < 0: " + unstable);
11049            }
11050
11051            if ((stable+unstable) <= 0) {
11052                throw new IllegalStateException("ref counts can't go to zero here: stable="
11053                        + stable + " unstable=" + unstable);
11054            }
11055            conn.stableCount = stable;
11056            conn.unstableCount = unstable;
11057            return !conn.dead;
11058        }
11059    }
11060
11061    public void unstableProviderDied(IBinder connection) {
11062        ContentProviderConnection conn;
11063        try {
11064            conn = (ContentProviderConnection)connection;
11065        } catch (ClassCastException e) {
11066            String msg ="refContentProvider: " + connection
11067                    + " not a ContentProviderConnection";
11068            Slog.w(TAG, msg);
11069            throw new IllegalArgumentException(msg);
11070        }
11071        if (conn == null) {
11072            throw new NullPointerException("connection is null");
11073        }
11074
11075        // Safely retrieve the content provider associated with the connection.
11076        IContentProvider provider;
11077        synchronized (this) {
11078            provider = conn.provider.provider;
11079        }
11080
11081        if (provider == null) {
11082            // Um, yeah, we're way ahead of you.
11083            return;
11084        }
11085
11086        // Make sure the caller is being honest with us.
11087        if (provider.asBinder().pingBinder()) {
11088            // Er, no, still looks good to us.
11089            synchronized (this) {
11090                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11091                        + " says " + conn + " died, but we don't agree");
11092                return;
11093            }
11094        }
11095
11096        // Well look at that!  It's dead!
11097        synchronized (this) {
11098            if (conn.provider.provider != provider) {
11099                // But something changed...  good enough.
11100                return;
11101            }
11102
11103            ProcessRecord proc = conn.provider.proc;
11104            if (proc == null || proc.thread == null) {
11105                // Seems like the process is already cleaned up.
11106                return;
11107            }
11108
11109            // As far as we're concerned, this is just like receiving a
11110            // death notification...  just a bit prematurely.
11111            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11112                    + ") early provider death");
11113            final long ident = Binder.clearCallingIdentity();
11114            try {
11115                appDiedLocked(proc);
11116            } finally {
11117                Binder.restoreCallingIdentity(ident);
11118            }
11119        }
11120    }
11121
11122    @Override
11123    public void appNotRespondingViaProvider(IBinder connection) {
11124        enforceCallingPermission(
11125                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11126
11127        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11128        if (conn == null) {
11129            Slog.w(TAG, "ContentProviderConnection is null");
11130            return;
11131        }
11132
11133        final ProcessRecord host = conn.provider.proc;
11134        if (host == null) {
11135            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11136            return;
11137        }
11138
11139        mHandler.post(new Runnable() {
11140            @Override
11141            public void run() {
11142                mAppErrors.appNotResponding(host, null, null, false,
11143                        "ContentProvider not responding");
11144            }
11145        });
11146    }
11147
11148    public final void installSystemProviders() {
11149        List<ProviderInfo> providers;
11150        synchronized (this) {
11151            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11152            providers = generateApplicationProvidersLocked(app);
11153            if (providers != null) {
11154                for (int i=providers.size()-1; i>=0; i--) {
11155                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11156                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11157                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11158                                + ": not system .apk");
11159                        providers.remove(i);
11160                    }
11161                }
11162            }
11163        }
11164        if (providers != null) {
11165            mSystemThread.installSystemProviders(providers);
11166        }
11167
11168        mCoreSettingsObserver = new CoreSettingsObserver(this);
11169        mFontScaleSettingObserver = new FontScaleSettingObserver();
11170
11171        //mUsageStatsService.monitorPackages();
11172    }
11173
11174    private void startPersistentApps(int matchFlags) {
11175        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11176
11177        synchronized (this) {
11178            try {
11179                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11180                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11181                for (ApplicationInfo app : apps) {
11182                    if (!"android".equals(app.packageName)) {
11183                        addAppLocked(app, false, null /* ABI override */);
11184                    }
11185                }
11186            } catch (RemoteException ex) {
11187            }
11188        }
11189    }
11190
11191    /**
11192     * When a user is unlocked, we need to install encryption-unaware providers
11193     * belonging to any running apps.
11194     */
11195    private void installEncryptionUnawareProviders(int userId) {
11196        // We're only interested in providers that are encryption unaware, and
11197        // we don't care about uninstalled apps, since there's no way they're
11198        // running at this point.
11199        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11200
11201        synchronized (this) {
11202            final int NP = mProcessNames.getMap().size();
11203            for (int ip = 0; ip < NP; ip++) {
11204                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11205                final int NA = apps.size();
11206                for (int ia = 0; ia < NA; ia++) {
11207                    final ProcessRecord app = apps.valueAt(ia);
11208                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11209
11210                    final int NG = app.pkgList.size();
11211                    for (int ig = 0; ig < NG; ig++) {
11212                        try {
11213                            final String pkgName = app.pkgList.keyAt(ig);
11214                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11215                                    .getPackageInfo(pkgName, matchFlags, userId);
11216                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11217                                for (ProviderInfo pi : pkgInfo.providers) {
11218                                    // TODO: keep in sync with generateApplicationProvidersLocked
11219                                    final boolean processMatch = Objects.equals(pi.processName,
11220                                            app.processName) || pi.multiprocess;
11221                                    final boolean userMatch = isSingleton(pi.processName,
11222                                            pi.applicationInfo, pi.name, pi.flags)
11223                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11224                                    if (processMatch && userMatch) {
11225                                        Log.v(TAG, "Installing " + pi);
11226                                        app.thread.scheduleInstallProvider(pi);
11227                                    } else {
11228                                        Log.v(TAG, "Skipping " + pi);
11229                                    }
11230                                }
11231                            }
11232                        } catch (RemoteException ignored) {
11233                        }
11234                    }
11235                }
11236            }
11237        }
11238    }
11239
11240    /**
11241     * Allows apps to retrieve the MIME type of a URI.
11242     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11243     * users, then it does not need permission to access the ContentProvider.
11244     * Either, it needs cross-user uri grants.
11245     *
11246     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11247     *
11248     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11249     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11250     */
11251    public String getProviderMimeType(Uri uri, int userId) {
11252        enforceNotIsolatedCaller("getProviderMimeType");
11253        final String name = uri.getAuthority();
11254        int callingUid = Binder.getCallingUid();
11255        int callingPid = Binder.getCallingPid();
11256        long ident = 0;
11257        boolean clearedIdentity = false;
11258        synchronized (this) {
11259            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11260        }
11261        if (canClearIdentity(callingPid, callingUid, userId)) {
11262            clearedIdentity = true;
11263            ident = Binder.clearCallingIdentity();
11264        }
11265        ContentProviderHolder holder = null;
11266        try {
11267            holder = getContentProviderExternalUnchecked(name, null, userId);
11268            if (holder != null) {
11269                return holder.provider.getType(uri);
11270            }
11271        } catch (RemoteException e) {
11272            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11273            return null;
11274        } catch (Exception e) {
11275            Log.w(TAG, "Exception while determining type of " + uri, e);
11276            return null;
11277        } finally {
11278            // We need to clear the identity to call removeContentProviderExternalUnchecked
11279            if (!clearedIdentity) {
11280                ident = Binder.clearCallingIdentity();
11281            }
11282            try {
11283                if (holder != null) {
11284                    removeContentProviderExternalUnchecked(name, null, userId);
11285                }
11286            } finally {
11287                Binder.restoreCallingIdentity(ident);
11288            }
11289        }
11290
11291        return null;
11292    }
11293
11294    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11295        if (UserHandle.getUserId(callingUid) == userId) {
11296            return true;
11297        }
11298        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11299                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11300                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11301                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11302                return true;
11303        }
11304        return false;
11305    }
11306
11307    // =========================================================
11308    // GLOBAL MANAGEMENT
11309    // =========================================================
11310
11311    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11312            boolean isolated, int isolatedUid) {
11313        String proc = customProcess != null ? customProcess : info.processName;
11314        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11315        final int userId = UserHandle.getUserId(info.uid);
11316        int uid = info.uid;
11317        if (isolated) {
11318            if (isolatedUid == 0) {
11319                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11320                while (true) {
11321                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11322                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11323                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11324                    }
11325                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11326                    mNextIsolatedProcessUid++;
11327                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11328                        // No process for this uid, use it.
11329                        break;
11330                    }
11331                    stepsLeft--;
11332                    if (stepsLeft <= 0) {
11333                        return null;
11334                    }
11335                }
11336            } else {
11337                // Special case for startIsolatedProcess (internal only), where
11338                // the uid of the isolated process is specified by the caller.
11339                uid = isolatedUid;
11340            }
11341        }
11342        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11343        if (!mBooted && !mBooting
11344                && userId == UserHandle.USER_SYSTEM
11345                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11346            r.persistent = true;
11347        }
11348        addProcessNameLocked(r);
11349        return r;
11350    }
11351
11352    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11353            String abiOverride) {
11354        ProcessRecord app;
11355        if (!isolated) {
11356            app = getProcessRecordLocked(info.processName, info.uid, true);
11357        } else {
11358            app = null;
11359        }
11360
11361        if (app == null) {
11362            app = newProcessRecordLocked(info, null, isolated, 0);
11363            updateLruProcessLocked(app, false, null);
11364            updateOomAdjLocked();
11365        }
11366
11367        // This package really, really can not be stopped.
11368        try {
11369            AppGlobals.getPackageManager().setPackageStoppedState(
11370                    info.packageName, false, UserHandle.getUserId(app.uid));
11371        } catch (RemoteException e) {
11372        } catch (IllegalArgumentException e) {
11373            Slog.w(TAG, "Failed trying to unstop package "
11374                    + info.packageName + ": " + e);
11375        }
11376
11377        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11378            app.persistent = true;
11379            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11380        }
11381        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11382            mPersistentStartingProcesses.add(app);
11383            startProcessLocked(app, "added application", app.processName, abiOverride,
11384                    null /* entryPoint */, null /* entryPointArgs */);
11385        }
11386
11387        return app;
11388    }
11389
11390    public void unhandledBack() {
11391        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11392                "unhandledBack()");
11393
11394        synchronized(this) {
11395            final long origId = Binder.clearCallingIdentity();
11396            try {
11397                getFocusedStack().unhandledBackLocked();
11398            } finally {
11399                Binder.restoreCallingIdentity(origId);
11400            }
11401        }
11402    }
11403
11404    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11405        enforceNotIsolatedCaller("openContentUri");
11406        final int userId = UserHandle.getCallingUserId();
11407        String name = uri.getAuthority();
11408        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11409        ParcelFileDescriptor pfd = null;
11410        if (cph != null) {
11411            // We record the binder invoker's uid in thread-local storage before
11412            // going to the content provider to open the file.  Later, in the code
11413            // that handles all permissions checks, we look for this uid and use
11414            // that rather than the Activity Manager's own uid.  The effect is that
11415            // we do the check against the caller's permissions even though it looks
11416            // to the content provider like the Activity Manager itself is making
11417            // the request.
11418            Binder token = new Binder();
11419            sCallerIdentity.set(new Identity(
11420                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11421            try {
11422                pfd = cph.provider.openFile(null, uri, "r", null, token);
11423            } catch (FileNotFoundException e) {
11424                // do nothing; pfd will be returned null
11425            } finally {
11426                // Ensure that whatever happens, we clean up the identity state
11427                sCallerIdentity.remove();
11428                // Ensure we're done with the provider.
11429                removeContentProviderExternalUnchecked(name, null, userId);
11430            }
11431        } else {
11432            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11433        }
11434        return pfd;
11435    }
11436
11437    // Actually is sleeping or shutting down or whatever else in the future
11438    // is an inactive state.
11439    public boolean isSleepingOrShuttingDown() {
11440        return isSleeping() || mShuttingDown;
11441    }
11442
11443    public boolean isSleeping() {
11444        return mSleeping;
11445    }
11446
11447    void onWakefulnessChanged(int wakefulness) {
11448        synchronized(this) {
11449            mWakefulness = wakefulness;
11450            updateSleepIfNeededLocked();
11451        }
11452    }
11453
11454    void finishRunningVoiceLocked() {
11455        if (mRunningVoice != null) {
11456            mRunningVoice = null;
11457            mVoiceWakeLock.release();
11458            updateSleepIfNeededLocked();
11459        }
11460    }
11461
11462    void startTimeTrackingFocusedActivityLocked() {
11463        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11464            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11465        }
11466    }
11467
11468    void updateSleepIfNeededLocked() {
11469        if (mSleeping && !shouldSleepLocked()) {
11470            mSleeping = false;
11471            startTimeTrackingFocusedActivityLocked();
11472            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11473            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11474            updateOomAdjLocked();
11475        } else if (!mSleeping && shouldSleepLocked()) {
11476            mSleeping = true;
11477            if (mCurAppTimeTracker != null) {
11478                mCurAppTimeTracker.stop();
11479            }
11480            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11481            mStackSupervisor.goingToSleepLocked();
11482            updateOomAdjLocked();
11483
11484            // Initialize the wake times of all processes.
11485            checkExcessivePowerUsageLocked(false);
11486            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11487            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11488            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11489        }
11490    }
11491
11492    private boolean shouldSleepLocked() {
11493        // Resume applications while running a voice interactor.
11494        if (mRunningVoice != null) {
11495            return false;
11496        }
11497
11498        // TODO: Transform the lock screen state into a sleep token instead.
11499        switch (mWakefulness) {
11500            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11501            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11502            case PowerManagerInternal.WAKEFULNESS_DOZING:
11503                // Pause applications whenever the lock screen is shown or any sleep
11504                // tokens have been acquired.
11505                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11506            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11507            default:
11508                // If we're asleep then pause applications unconditionally.
11509                return true;
11510        }
11511    }
11512
11513    /** Pokes the task persister. */
11514    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11515        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11516    }
11517
11518    /** Notifies all listeners when the task stack has changed. */
11519    void notifyTaskStackChangedLocked() {
11520        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11521        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11522        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11523        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11524    }
11525
11526    /** Notifies all listeners when an Activity is pinned. */
11527    void notifyActivityPinnedLocked() {
11528        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11529        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11530    }
11531
11532    /**
11533     * Notifies all listeners when an attempt was made to start an an activity that is already
11534     * running in the pinned stack and the activity was not actually started, but the task is
11535     * either brought to the front or a new Intent is delivered to it.
11536     */
11537    void notifyPinnedActivityRestartAttemptLocked() {
11538        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11539        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11540    }
11541
11542    /** Notifies all listeners when the pinned stack animation ends. */
11543    @Override
11544    public void notifyPinnedStackAnimationEnded() {
11545        synchronized (this) {
11546            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11547            mHandler.obtainMessage(
11548                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11549        }
11550    }
11551
11552    @Override
11553    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11554        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11555    }
11556
11557    @Override
11558    public boolean shutdown(int timeout) {
11559        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11560                != PackageManager.PERMISSION_GRANTED) {
11561            throw new SecurityException("Requires permission "
11562                    + android.Manifest.permission.SHUTDOWN);
11563        }
11564
11565        boolean timedout = false;
11566
11567        synchronized(this) {
11568            mShuttingDown = true;
11569            updateEventDispatchingLocked();
11570            timedout = mStackSupervisor.shutdownLocked(timeout);
11571        }
11572
11573        mAppOpsService.shutdown();
11574        if (mUsageStatsService != null) {
11575            mUsageStatsService.prepareShutdown();
11576        }
11577        mBatteryStatsService.shutdown();
11578        synchronized (this) {
11579            mProcessStats.shutdownLocked();
11580            notifyTaskPersisterLocked(null, true);
11581        }
11582
11583        return timedout;
11584    }
11585
11586    public final void activitySlept(IBinder token) {
11587        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11588
11589        final long origId = Binder.clearCallingIdentity();
11590
11591        synchronized (this) {
11592            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11593            if (r != null) {
11594                mStackSupervisor.activitySleptLocked(r);
11595            }
11596        }
11597
11598        Binder.restoreCallingIdentity(origId);
11599    }
11600
11601    private String lockScreenShownToString() {
11602        switch (mLockScreenShown) {
11603            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11604            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11605            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11606            default: return "Unknown=" + mLockScreenShown;
11607        }
11608    }
11609
11610    void logLockScreen(String msg) {
11611        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11612                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11613                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11614                + " mSleeping=" + mSleeping);
11615    }
11616
11617    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11618        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11619        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11620        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11621            boolean wasRunningVoice = mRunningVoice != null;
11622            mRunningVoice = session;
11623            if (!wasRunningVoice) {
11624                mVoiceWakeLock.acquire();
11625                updateSleepIfNeededLocked();
11626            }
11627        }
11628    }
11629
11630    private void updateEventDispatchingLocked() {
11631        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11632    }
11633
11634    public void setLockScreenShown(boolean showing, boolean occluded) {
11635        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11636                != PackageManager.PERMISSION_GRANTED) {
11637            throw new SecurityException("Requires permission "
11638                    + android.Manifest.permission.DEVICE_POWER);
11639        }
11640
11641        synchronized(this) {
11642            long ident = Binder.clearCallingIdentity();
11643            try {
11644                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11645                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11646                if (showing && occluded) {
11647                    // The lock screen is currently showing, but is occluded by a window that can
11648                    // show on top of the lock screen. In this can we want to dismiss the docked
11649                    // stack since it will be complicated/risky to try to put the activity on top
11650                    // of the lock screen in the right fullscreen configuration.
11651                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11652                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11653                }
11654
11655                updateSleepIfNeededLocked();
11656            } finally {
11657                Binder.restoreCallingIdentity(ident);
11658            }
11659        }
11660    }
11661
11662    @Override
11663    public void notifyLockedProfile(@UserIdInt int userId) {
11664        try {
11665            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11666                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11667            }
11668        } catch (RemoteException ex) {
11669            throw new SecurityException("Fail to check is caller a privileged app", ex);
11670        }
11671
11672        synchronized (this) {
11673            if (mStackSupervisor.isUserLockedProfile(userId)) {
11674                final long ident = Binder.clearCallingIdentity();
11675                try {
11676                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11677                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11678                        // If there is no device lock, we will show the profile's credential page.
11679                        mActivityStarter.showConfirmDeviceCredential(userId);
11680                    } else {
11681                        // Showing launcher to avoid user entering credential twice.
11682                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11683                    }
11684                } finally {
11685                    Binder.restoreCallingIdentity(ident);
11686                }
11687            }
11688        }
11689    }
11690
11691    @Override
11692    public void startConfirmDeviceCredentialIntent(Intent intent) {
11693        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11694        synchronized (this) {
11695            final long ident = Binder.clearCallingIdentity();
11696            try {
11697                mActivityStarter.startConfirmCredentialIntent(intent);
11698            } finally {
11699                Binder.restoreCallingIdentity(ident);
11700            }
11701        }
11702    }
11703
11704    @Override
11705    public void stopAppSwitches() {
11706        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11707                != PackageManager.PERMISSION_GRANTED) {
11708            throw new SecurityException("viewquires permission "
11709                    + android.Manifest.permission.STOP_APP_SWITCHES);
11710        }
11711
11712        synchronized(this) {
11713            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11714                    + APP_SWITCH_DELAY_TIME;
11715            mDidAppSwitch = false;
11716            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11717            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11718            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11719        }
11720    }
11721
11722    public void resumeAppSwitches() {
11723        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11724                != PackageManager.PERMISSION_GRANTED) {
11725            throw new SecurityException("Requires permission "
11726                    + android.Manifest.permission.STOP_APP_SWITCHES);
11727        }
11728
11729        synchronized(this) {
11730            // Note that we don't execute any pending app switches... we will
11731            // let those wait until either the timeout, or the next start
11732            // activity request.
11733            mAppSwitchesAllowedTime = 0;
11734        }
11735    }
11736
11737    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11738            int callingPid, int callingUid, String name) {
11739        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11740            return true;
11741        }
11742
11743        int perm = checkComponentPermission(
11744                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11745                sourceUid, -1, true);
11746        if (perm == PackageManager.PERMISSION_GRANTED) {
11747            return true;
11748        }
11749
11750        // If the actual IPC caller is different from the logical source, then
11751        // also see if they are allowed to control app switches.
11752        if (callingUid != -1 && callingUid != sourceUid) {
11753            perm = checkComponentPermission(
11754                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11755                    callingUid, -1, true);
11756            if (perm == PackageManager.PERMISSION_GRANTED) {
11757                return true;
11758            }
11759        }
11760
11761        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11762        return false;
11763    }
11764
11765    public void setDebugApp(String packageName, boolean waitForDebugger,
11766            boolean persistent) {
11767        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11768                "setDebugApp()");
11769
11770        long ident = Binder.clearCallingIdentity();
11771        try {
11772            // Note that this is not really thread safe if there are multiple
11773            // callers into it at the same time, but that's not a situation we
11774            // care about.
11775            if (persistent) {
11776                final ContentResolver resolver = mContext.getContentResolver();
11777                Settings.Global.putString(
11778                    resolver, Settings.Global.DEBUG_APP,
11779                    packageName);
11780                Settings.Global.putInt(
11781                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11782                    waitForDebugger ? 1 : 0);
11783            }
11784
11785            synchronized (this) {
11786                if (!persistent) {
11787                    mOrigDebugApp = mDebugApp;
11788                    mOrigWaitForDebugger = mWaitForDebugger;
11789                }
11790                mDebugApp = packageName;
11791                mWaitForDebugger = waitForDebugger;
11792                mDebugTransient = !persistent;
11793                if (packageName != null) {
11794                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11795                            false, UserHandle.USER_ALL, "set debug app");
11796                }
11797            }
11798        } finally {
11799            Binder.restoreCallingIdentity(ident);
11800        }
11801    }
11802
11803    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11804        synchronized (this) {
11805            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11806            if (!isDebuggable) {
11807                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11808                    throw new SecurityException("Process not debuggable: " + app.packageName);
11809                }
11810            }
11811
11812            mTrackAllocationApp = processName;
11813        }
11814    }
11815
11816    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11817        synchronized (this) {
11818            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11819            if (!isDebuggable) {
11820                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11821                    throw new SecurityException("Process not debuggable: " + app.packageName);
11822                }
11823            }
11824            mProfileApp = processName;
11825            mProfileFile = profilerInfo.profileFile;
11826            if (mProfileFd != null) {
11827                try {
11828                    mProfileFd.close();
11829                } catch (IOException e) {
11830                }
11831                mProfileFd = null;
11832            }
11833            mProfileFd = profilerInfo.profileFd;
11834            mSamplingInterval = profilerInfo.samplingInterval;
11835            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11836            mProfileType = 0;
11837        }
11838    }
11839
11840    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11841        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11842        if (!isDebuggable) {
11843            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11844                throw new SecurityException("Process not debuggable: " + app.packageName);
11845            }
11846        }
11847        mNativeDebuggingApp = processName;
11848    }
11849
11850    @Override
11851    public void setAlwaysFinish(boolean enabled) {
11852        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11853                "setAlwaysFinish()");
11854
11855        long ident = Binder.clearCallingIdentity();
11856        try {
11857            Settings.Global.putInt(
11858                    mContext.getContentResolver(),
11859                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11860
11861            synchronized (this) {
11862                mAlwaysFinishActivities = enabled;
11863            }
11864        } finally {
11865            Binder.restoreCallingIdentity(ident);
11866        }
11867    }
11868
11869    @Override
11870    public void setLenientBackgroundCheck(boolean enabled) {
11871        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11872                "setLenientBackgroundCheck()");
11873
11874        long ident = Binder.clearCallingIdentity();
11875        try {
11876            Settings.Global.putInt(
11877                    mContext.getContentResolver(),
11878                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11879
11880            synchronized (this) {
11881                mLenientBackgroundCheck = enabled;
11882            }
11883        } finally {
11884            Binder.restoreCallingIdentity(ident);
11885        }
11886    }
11887
11888    @Override
11889    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11890        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11891                "setActivityController()");
11892        synchronized (this) {
11893            mController = controller;
11894            mControllerIsAMonkey = imAMonkey;
11895            Watchdog.getInstance().setActivityController(controller);
11896        }
11897    }
11898
11899    @Override
11900    public void setUserIsMonkey(boolean userIsMonkey) {
11901        synchronized (this) {
11902            synchronized (mPidsSelfLocked) {
11903                final int callingPid = Binder.getCallingPid();
11904                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11905                if (precessRecord == null) {
11906                    throw new SecurityException("Unknown process: " + callingPid);
11907                }
11908                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11909                    throw new SecurityException("Only an instrumentation process "
11910                            + "with a UiAutomation can call setUserIsMonkey");
11911                }
11912            }
11913            mUserIsMonkey = userIsMonkey;
11914        }
11915    }
11916
11917    @Override
11918    public boolean isUserAMonkey() {
11919        synchronized (this) {
11920            // If there is a controller also implies the user is a monkey.
11921            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11922        }
11923    }
11924
11925    public void requestBugReport(int bugreportType) {
11926        String service = null;
11927        switch (bugreportType) {
11928            case ActivityManager.BUGREPORT_OPTION_FULL:
11929                service = "bugreport";
11930                break;
11931            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11932                service = "bugreportplus";
11933                break;
11934            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11935                service = "bugreportremote";
11936                break;
11937        }
11938        if (service == null) {
11939            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11940                    + bugreportType);
11941        }
11942        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11943        SystemProperties.set("ctl.start", service);
11944    }
11945
11946    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11947        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11948    }
11949
11950    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11951        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11952            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11953        }
11954        return KEY_DISPATCHING_TIMEOUT;
11955    }
11956
11957    @Override
11958    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11959        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11960                != PackageManager.PERMISSION_GRANTED) {
11961            throw new SecurityException("Requires permission "
11962                    + android.Manifest.permission.FILTER_EVENTS);
11963        }
11964        ProcessRecord proc;
11965        long timeout;
11966        synchronized (this) {
11967            synchronized (mPidsSelfLocked) {
11968                proc = mPidsSelfLocked.get(pid);
11969            }
11970            timeout = getInputDispatchingTimeoutLocked(proc);
11971        }
11972
11973        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11974            return -1;
11975        }
11976
11977        return timeout;
11978    }
11979
11980    /**
11981     * Handle input dispatching timeouts.
11982     * Returns whether input dispatching should be aborted or not.
11983     */
11984    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11985            final ActivityRecord activity, final ActivityRecord parent,
11986            final boolean aboveSystem, String reason) {
11987        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11988                != PackageManager.PERMISSION_GRANTED) {
11989            throw new SecurityException("Requires permission "
11990                    + android.Manifest.permission.FILTER_EVENTS);
11991        }
11992
11993        final String annotation;
11994        if (reason == null) {
11995            annotation = "Input dispatching timed out";
11996        } else {
11997            annotation = "Input dispatching timed out (" + reason + ")";
11998        }
11999
12000        if (proc != null) {
12001            synchronized (this) {
12002                if (proc.debugging) {
12003                    return false;
12004                }
12005
12006                if (mDidDexOpt) {
12007                    // Give more time since we were dexopting.
12008                    mDidDexOpt = false;
12009                    return false;
12010                }
12011
12012                if (proc.instrumentationClass != null) {
12013                    Bundle info = new Bundle();
12014                    info.putString("shortMsg", "keyDispatchingTimedOut");
12015                    info.putString("longMsg", annotation);
12016                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12017                    return true;
12018                }
12019            }
12020            mHandler.post(new Runnable() {
12021                @Override
12022                public void run() {
12023                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12024                }
12025            });
12026        }
12027
12028        return true;
12029    }
12030
12031    @Override
12032    public Bundle getAssistContextExtras(int requestType) {
12033        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12034                null, null, true /* focused */, true /* newSessionId */,
12035                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12036        if (pae == null) {
12037            return null;
12038        }
12039        synchronized (pae) {
12040            while (!pae.haveResult) {
12041                try {
12042                    pae.wait();
12043                } catch (InterruptedException e) {
12044                }
12045            }
12046        }
12047        synchronized (this) {
12048            buildAssistBundleLocked(pae, pae.result);
12049            mPendingAssistExtras.remove(pae);
12050            mUiHandler.removeCallbacks(pae);
12051        }
12052        return pae.extras;
12053    }
12054
12055    @Override
12056    public boolean isAssistDataAllowedOnCurrentActivity() {
12057        int userId;
12058        synchronized (this) {
12059            userId = mUserController.getCurrentUserIdLocked();
12060            ActivityRecord activity = getFocusedStack().topActivity();
12061            if (activity == null) {
12062                return false;
12063            }
12064            userId = activity.userId;
12065        }
12066        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12067                Context.DEVICE_POLICY_SERVICE);
12068        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12069    }
12070
12071    @Override
12072    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12073        long ident = Binder.clearCallingIdentity();
12074        try {
12075            synchronized (this) {
12076                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12077                ActivityRecord top = getFocusedStack().topActivity();
12078                if (top != caller) {
12079                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12080                            + " is not current top " + top);
12081                    return false;
12082                }
12083                if (!top.nowVisible) {
12084                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12085                            + " is not visible");
12086                    return false;
12087                }
12088            }
12089            AssistUtils utils = new AssistUtils(mContext);
12090            return utils.showSessionForActiveService(args,
12091                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12092        } finally {
12093            Binder.restoreCallingIdentity(ident);
12094        }
12095    }
12096
12097    @Override
12098    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12099            Bundle receiverExtras,
12100            IBinder activityToken, boolean focused, boolean newSessionId) {
12101        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12102                activityToken, focused, newSessionId,
12103                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12104                != null;
12105    }
12106
12107    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12108            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12109            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12110        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12111                "enqueueAssistContext()");
12112        synchronized (this) {
12113            ActivityRecord activity = getFocusedStack().topActivity();
12114            if (activity == null) {
12115                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12116                return null;
12117            }
12118            if (activity.app == null || activity.app.thread == null) {
12119                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12120                return null;
12121            }
12122            if (focused) {
12123                if (activityToken != null) {
12124                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12125                    if (activity != caller) {
12126                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12127                                + " is not current top " + activity);
12128                        return null;
12129                    }
12130                }
12131            } else {
12132                activity = ActivityRecord.forTokenLocked(activityToken);
12133                if (activity == null) {
12134                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12135                            + " couldn't be found");
12136                    return null;
12137                }
12138            }
12139
12140            PendingAssistExtras pae;
12141            Bundle extras = new Bundle();
12142            if (args != null) {
12143                extras.putAll(args);
12144            }
12145            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12146            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12147            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12148                    userHandle);
12149            // Increment the sessionId if necessary
12150            if (newSessionId) {
12151                mViSessionId++;
12152            }
12153            try {
12154                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12155                        requestType, mViSessionId);
12156                mPendingAssistExtras.add(pae);
12157                mUiHandler.postDelayed(pae, timeout);
12158            } catch (RemoteException e) {
12159                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12160                return null;
12161            }
12162            return pae;
12163        }
12164    }
12165
12166    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12167        IResultReceiver receiver;
12168        synchronized (this) {
12169            mPendingAssistExtras.remove(pae);
12170            receiver = pae.receiver;
12171        }
12172        if (receiver != null) {
12173            // Caller wants result sent back to them.
12174            Bundle sendBundle = new Bundle();
12175            // At least return the receiver extras
12176            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12177                    pae.receiverExtras);
12178            try {
12179                pae.receiver.send(0, sendBundle);
12180            } catch (RemoteException e) {
12181            }
12182        }
12183    }
12184
12185    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12186        if (result != null) {
12187            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12188        }
12189        if (pae.hint != null) {
12190            pae.extras.putBoolean(pae.hint, true);
12191        }
12192    }
12193
12194    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12195            AssistContent content, Uri referrer) {
12196        PendingAssistExtras pae = (PendingAssistExtras)token;
12197        synchronized (pae) {
12198            pae.result = extras;
12199            pae.structure = structure;
12200            pae.content = content;
12201            if (referrer != null) {
12202                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12203            }
12204            pae.haveResult = true;
12205            pae.notifyAll();
12206            if (pae.intent == null && pae.receiver == null) {
12207                // Caller is just waiting for the result.
12208                return;
12209            }
12210        }
12211
12212        // We are now ready to launch the assist activity.
12213        IResultReceiver sendReceiver = null;
12214        Bundle sendBundle = null;
12215        synchronized (this) {
12216            buildAssistBundleLocked(pae, extras);
12217            boolean exists = mPendingAssistExtras.remove(pae);
12218            mUiHandler.removeCallbacks(pae);
12219            if (!exists) {
12220                // Timed out.
12221                return;
12222            }
12223            if ((sendReceiver=pae.receiver) != null) {
12224                // Caller wants result sent back to them.
12225                sendBundle = new Bundle();
12226                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12227                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12228                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12229                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12230                        pae.receiverExtras);
12231            }
12232        }
12233        if (sendReceiver != null) {
12234            try {
12235                sendReceiver.send(0, sendBundle);
12236            } catch (RemoteException e) {
12237            }
12238            return;
12239        }
12240
12241        long ident = Binder.clearCallingIdentity();
12242        try {
12243            pae.intent.replaceExtras(pae.extras);
12244            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12245                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12246                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12247            closeSystemDialogs("assist");
12248            try {
12249                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12250            } catch (ActivityNotFoundException e) {
12251                Slog.w(TAG, "No activity to handle assist action.", e);
12252            }
12253        } finally {
12254            Binder.restoreCallingIdentity(ident);
12255        }
12256    }
12257
12258    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12259            Bundle args) {
12260        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12261                true /* focused */, true /* newSessionId */,
12262                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12263    }
12264
12265    public void registerProcessObserver(IProcessObserver observer) {
12266        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12267                "registerProcessObserver()");
12268        synchronized (this) {
12269            mProcessObservers.register(observer);
12270        }
12271    }
12272
12273    @Override
12274    public void unregisterProcessObserver(IProcessObserver observer) {
12275        synchronized (this) {
12276            mProcessObservers.unregister(observer);
12277        }
12278    }
12279
12280    @Override
12281    public void registerUidObserver(IUidObserver observer, int which) {
12282        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12283                "registerUidObserver()");
12284        synchronized (this) {
12285            mUidObservers.register(observer, which);
12286        }
12287    }
12288
12289    @Override
12290    public void unregisterUidObserver(IUidObserver observer) {
12291        synchronized (this) {
12292            mUidObservers.unregister(observer);
12293        }
12294    }
12295
12296    @Override
12297    public boolean convertFromTranslucent(IBinder token) {
12298        final long origId = Binder.clearCallingIdentity();
12299        try {
12300            synchronized (this) {
12301                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12302                if (r == null) {
12303                    return false;
12304                }
12305                final boolean translucentChanged = r.changeWindowTranslucency(true);
12306                if (translucentChanged) {
12307                    r.task.stack.releaseBackgroundResources(r);
12308                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12309                }
12310                mWindowManager.setAppFullscreen(token, true);
12311                return translucentChanged;
12312            }
12313        } finally {
12314            Binder.restoreCallingIdentity(origId);
12315        }
12316    }
12317
12318    @Override
12319    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12320        final long origId = Binder.clearCallingIdentity();
12321        try {
12322            synchronized (this) {
12323                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12324                if (r == null) {
12325                    return false;
12326                }
12327                int index = r.task.mActivities.lastIndexOf(r);
12328                if (index > 0) {
12329                    ActivityRecord under = r.task.mActivities.get(index - 1);
12330                    under.returningOptions = options;
12331                }
12332                final boolean translucentChanged = r.changeWindowTranslucency(false);
12333                if (translucentChanged) {
12334                    r.task.stack.convertActivityToTranslucent(r);
12335                }
12336                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12337                mWindowManager.setAppFullscreen(token, false);
12338                return translucentChanged;
12339            }
12340        } finally {
12341            Binder.restoreCallingIdentity(origId);
12342        }
12343    }
12344
12345    @Override
12346    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12347        final long origId = Binder.clearCallingIdentity();
12348        try {
12349            synchronized (this) {
12350                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12351                if (r != null) {
12352                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12353                }
12354            }
12355            return false;
12356        } finally {
12357            Binder.restoreCallingIdentity(origId);
12358        }
12359    }
12360
12361    @Override
12362    public boolean isBackgroundVisibleBehind(IBinder token) {
12363        final long origId = Binder.clearCallingIdentity();
12364        try {
12365            synchronized (this) {
12366                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12367                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12368                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12369                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12370                return visible;
12371            }
12372        } finally {
12373            Binder.restoreCallingIdentity(origId);
12374        }
12375    }
12376
12377    @Override
12378    public ActivityOptions getActivityOptions(IBinder token) {
12379        final long origId = Binder.clearCallingIdentity();
12380        try {
12381            synchronized (this) {
12382                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12383                if (r != null) {
12384                    final ActivityOptions activityOptions = r.pendingOptions;
12385                    r.pendingOptions = null;
12386                    return activityOptions;
12387                }
12388                return null;
12389            }
12390        } finally {
12391            Binder.restoreCallingIdentity(origId);
12392        }
12393    }
12394
12395    @Override
12396    public void setImmersive(IBinder token, boolean immersive) {
12397        synchronized(this) {
12398            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12399            if (r == null) {
12400                throw new IllegalArgumentException();
12401            }
12402            r.immersive = immersive;
12403
12404            // update associated state if we're frontmost
12405            if (r == mFocusedActivity) {
12406                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12407                applyUpdateLockStateLocked(r);
12408            }
12409        }
12410    }
12411
12412    @Override
12413    public boolean isImmersive(IBinder token) {
12414        synchronized (this) {
12415            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12416            if (r == null) {
12417                throw new IllegalArgumentException();
12418            }
12419            return r.immersive;
12420        }
12421    }
12422
12423    @Override
12424    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12425        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12426            throw new UnsupportedOperationException("VR mode not supported on this device!");
12427        }
12428
12429        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12430
12431        ActivityRecord r;
12432        synchronized (this) {
12433            r = ActivityRecord.isInStackLocked(token);
12434        }
12435
12436        if (r == null) {
12437            throw new IllegalArgumentException();
12438        }
12439
12440        int err;
12441        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12442                VrManagerInternal.NO_ERROR) {
12443            return err;
12444        }
12445
12446        synchronized(this) {
12447            r.requestedVrComponent = (enabled) ? packageName : null;
12448
12449            // Update associated state if this activity is currently focused
12450            if (r == mFocusedActivity) {
12451                applyUpdateVrModeLocked(r);
12452            }
12453            return 0;
12454        }
12455    }
12456
12457    @Override
12458    public boolean isVrModePackageEnabled(ComponentName packageName) {
12459        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12460            throw new UnsupportedOperationException("VR mode not supported on this device!");
12461        }
12462
12463        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12464
12465        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12466                VrManagerInternal.NO_ERROR;
12467    }
12468
12469    public boolean isTopActivityImmersive() {
12470        enforceNotIsolatedCaller("startActivity");
12471        synchronized (this) {
12472            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12473            return (r != null) ? r.immersive : false;
12474        }
12475    }
12476
12477    @Override
12478    public boolean isTopOfTask(IBinder token) {
12479        synchronized (this) {
12480            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12481            if (r == null) {
12482                throw new IllegalArgumentException();
12483            }
12484            return r.task.getTopActivity() == r;
12485        }
12486    }
12487
12488    public final void enterSafeMode() {
12489        synchronized(this) {
12490            // It only makes sense to do this before the system is ready
12491            // and started launching other packages.
12492            if (!mSystemReady) {
12493                try {
12494                    AppGlobals.getPackageManager().enterSafeMode();
12495                } catch (RemoteException e) {
12496                }
12497            }
12498
12499            mSafeMode = true;
12500        }
12501    }
12502
12503    public final void showSafeModeOverlay() {
12504        View v = LayoutInflater.from(mContext).inflate(
12505                com.android.internal.R.layout.safe_mode, null);
12506        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12507        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12508        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12509        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12510        lp.gravity = Gravity.BOTTOM | Gravity.START;
12511        lp.format = v.getBackground().getOpacity();
12512        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12513                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12514        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12515        ((WindowManager)mContext.getSystemService(
12516                Context.WINDOW_SERVICE)).addView(v, lp);
12517    }
12518
12519    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12520        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12521            return;
12522        }
12523        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12524        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12525        synchronized (stats) {
12526            if (mBatteryStatsService.isOnBattery()) {
12527                mBatteryStatsService.enforceCallingPermission();
12528                int MY_UID = Binder.getCallingUid();
12529                final int uid;
12530                if (sender == null) {
12531                    uid = sourceUid;
12532                } else {
12533                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12534                }
12535                BatteryStatsImpl.Uid.Pkg pkg =
12536                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12537                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12538                pkg.noteWakeupAlarmLocked(tag);
12539            }
12540        }
12541    }
12542
12543    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12544        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12545            return;
12546        }
12547        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12548        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12549        synchronized (stats) {
12550            mBatteryStatsService.enforceCallingPermission();
12551            int MY_UID = Binder.getCallingUid();
12552            final int uid;
12553            if (sender == null) {
12554                uid = sourceUid;
12555            } else {
12556                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12557            }
12558            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12559        }
12560    }
12561
12562    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12563        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12564            return;
12565        }
12566        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12567        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12568        synchronized (stats) {
12569            mBatteryStatsService.enforceCallingPermission();
12570            int MY_UID = Binder.getCallingUid();
12571            final int uid;
12572            if (sender == null) {
12573                uid = sourceUid;
12574            } else {
12575                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12576            }
12577            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12578        }
12579    }
12580
12581    public boolean killPids(int[] pids, String pReason, boolean secure) {
12582        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12583            throw new SecurityException("killPids only available to the system");
12584        }
12585        String reason = (pReason == null) ? "Unknown" : pReason;
12586        // XXX Note: don't acquire main activity lock here, because the window
12587        // manager calls in with its locks held.
12588
12589        boolean killed = false;
12590        synchronized (mPidsSelfLocked) {
12591            int worstType = 0;
12592            for (int i=0; i<pids.length; i++) {
12593                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12594                if (proc != null) {
12595                    int type = proc.setAdj;
12596                    if (type > worstType) {
12597                        worstType = type;
12598                    }
12599                }
12600            }
12601
12602            // If the worst oom_adj is somewhere in the cached proc LRU range,
12603            // then constrain it so we will kill all cached procs.
12604            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12605                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12606                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12607            }
12608
12609            // If this is not a secure call, don't let it kill processes that
12610            // are important.
12611            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12612                worstType = ProcessList.SERVICE_ADJ;
12613            }
12614
12615            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12616            for (int i=0; i<pids.length; i++) {
12617                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12618                if (proc == null) {
12619                    continue;
12620                }
12621                int adj = proc.setAdj;
12622                if (adj >= worstType && !proc.killedByAm) {
12623                    proc.kill(reason, true);
12624                    killed = true;
12625                }
12626            }
12627        }
12628        return killed;
12629    }
12630
12631    @Override
12632    public void killUid(int appId, int userId, String reason) {
12633        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12634        synchronized (this) {
12635            final long identity = Binder.clearCallingIdentity();
12636            try {
12637                killPackageProcessesLocked(null, appId, userId,
12638                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12639                        reason != null ? reason : "kill uid");
12640            } finally {
12641                Binder.restoreCallingIdentity(identity);
12642            }
12643        }
12644    }
12645
12646    @Override
12647    public boolean killProcessesBelowForeground(String reason) {
12648        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12649            throw new SecurityException("killProcessesBelowForeground() only available to system");
12650        }
12651
12652        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12653    }
12654
12655    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12656        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12657            throw new SecurityException("killProcessesBelowAdj() only available to system");
12658        }
12659
12660        boolean killed = false;
12661        synchronized (mPidsSelfLocked) {
12662            final int size = mPidsSelfLocked.size();
12663            for (int i = 0; i < size; i++) {
12664                final int pid = mPidsSelfLocked.keyAt(i);
12665                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12666                if (proc == null) continue;
12667
12668                final int adj = proc.setAdj;
12669                if (adj > belowAdj && !proc.killedByAm) {
12670                    proc.kill(reason, true);
12671                    killed = true;
12672                }
12673            }
12674        }
12675        return killed;
12676    }
12677
12678    @Override
12679    public void hang(final IBinder who, boolean allowRestart) {
12680        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12681                != PackageManager.PERMISSION_GRANTED) {
12682            throw new SecurityException("Requires permission "
12683                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12684        }
12685
12686        final IBinder.DeathRecipient death = new DeathRecipient() {
12687            @Override
12688            public void binderDied() {
12689                synchronized (this) {
12690                    notifyAll();
12691                }
12692            }
12693        };
12694
12695        try {
12696            who.linkToDeath(death, 0);
12697        } catch (RemoteException e) {
12698            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12699            return;
12700        }
12701
12702        synchronized (this) {
12703            Watchdog.getInstance().setAllowRestart(allowRestart);
12704            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12705            synchronized (death) {
12706                while (who.isBinderAlive()) {
12707                    try {
12708                        death.wait();
12709                    } catch (InterruptedException e) {
12710                    }
12711                }
12712            }
12713            Watchdog.getInstance().setAllowRestart(true);
12714        }
12715    }
12716
12717    @Override
12718    public void restart() {
12719        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12720                != PackageManager.PERMISSION_GRANTED) {
12721            throw new SecurityException("Requires permission "
12722                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12723        }
12724
12725        Log.i(TAG, "Sending shutdown broadcast...");
12726
12727        BroadcastReceiver br = new BroadcastReceiver() {
12728            @Override public void onReceive(Context context, Intent intent) {
12729                // Now the broadcast is done, finish up the low-level shutdown.
12730                Log.i(TAG, "Shutting down activity manager...");
12731                shutdown(10000);
12732                Log.i(TAG, "Shutdown complete, restarting!");
12733                Process.killProcess(Process.myPid());
12734                System.exit(10);
12735            }
12736        };
12737
12738        // First send the high-level shut down broadcast.
12739        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12740        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12741        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12742        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12743        mContext.sendOrderedBroadcastAsUser(intent,
12744                UserHandle.ALL, null, br, mHandler, 0, null, null);
12745        */
12746        br.onReceive(mContext, intent);
12747    }
12748
12749    private long getLowRamTimeSinceIdle(long now) {
12750        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12751    }
12752
12753    @Override
12754    public void performIdleMaintenance() {
12755        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12756                != PackageManager.PERMISSION_GRANTED) {
12757            throw new SecurityException("Requires permission "
12758                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12759        }
12760
12761        synchronized (this) {
12762            final long now = SystemClock.uptimeMillis();
12763            final long timeSinceLastIdle = now - mLastIdleTime;
12764            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12765            mLastIdleTime = now;
12766            mLowRamTimeSinceLastIdle = 0;
12767            if (mLowRamStartTime != 0) {
12768                mLowRamStartTime = now;
12769            }
12770
12771            StringBuilder sb = new StringBuilder(128);
12772            sb.append("Idle maintenance over ");
12773            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12774            sb.append(" low RAM for ");
12775            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12776            Slog.i(TAG, sb.toString());
12777
12778            // If at least 1/3 of our time since the last idle period has been spent
12779            // with RAM low, then we want to kill processes.
12780            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12781
12782            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12783                ProcessRecord proc = mLruProcesses.get(i);
12784                if (proc.notCachedSinceIdle) {
12785                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12786                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12787                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12788                        if (doKilling && proc.initialIdlePss != 0
12789                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12790                            sb = new StringBuilder(128);
12791                            sb.append("Kill");
12792                            sb.append(proc.processName);
12793                            sb.append(" in idle maint: pss=");
12794                            sb.append(proc.lastPss);
12795                            sb.append(", swapPss=");
12796                            sb.append(proc.lastSwapPss);
12797                            sb.append(", initialPss=");
12798                            sb.append(proc.initialIdlePss);
12799                            sb.append(", period=");
12800                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12801                            sb.append(", lowRamPeriod=");
12802                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12803                            Slog.wtfQuiet(TAG, sb.toString());
12804                            proc.kill("idle maint (pss " + proc.lastPss
12805                                    + " from " + proc.initialIdlePss + ")", true);
12806                        }
12807                    }
12808                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12809                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12810                    proc.notCachedSinceIdle = true;
12811                    proc.initialIdlePss = 0;
12812                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12813                            mTestPssMode, isSleeping(), now);
12814                }
12815            }
12816
12817            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12818            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12819        }
12820    }
12821
12822    @Override
12823    public void sendIdleJobTrigger() {
12824        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12825                != PackageManager.PERMISSION_GRANTED) {
12826            throw new SecurityException("Requires permission "
12827                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12828        }
12829
12830        final long ident = Binder.clearCallingIdentity();
12831        try {
12832            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12833                    .setPackage("android")
12834                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12835            broadcastIntent(null, intent, null, null, 0, null, null, null,
12836                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12837        } finally {
12838            Binder.restoreCallingIdentity(ident);
12839        }
12840    }
12841
12842    private void retrieveSettings() {
12843        final ContentResolver resolver = mContext.getContentResolver();
12844        final boolean freeformWindowManagement =
12845                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12846                        || Settings.Global.getInt(
12847                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12848        final boolean supportsPictureInPicture =
12849                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12850
12851        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12852        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12853        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12854        final boolean alwaysFinishActivities =
12855                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12856        final boolean lenientBackgroundCheck =
12857                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12858        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12859        final boolean forceResizable = Settings.Global.getInt(
12860                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12861        final boolean supportsLeanbackOnly =
12862                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12863
12864        // Transfer any global setting for forcing RTL layout, into a System Property
12865        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12866
12867        final Configuration configuration = new Configuration();
12868        Settings.System.getConfiguration(resolver, configuration);
12869        if (forceRtl) {
12870            // This will take care of setting the correct layout direction flags
12871            configuration.setLayoutDirection(configuration.locale);
12872        }
12873
12874        synchronized (this) {
12875            mDebugApp = mOrigDebugApp = debugApp;
12876            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12877            mAlwaysFinishActivities = alwaysFinishActivities;
12878            mLenientBackgroundCheck = lenientBackgroundCheck;
12879            mSupportsLeanbackOnly = supportsLeanbackOnly;
12880            mForceResizableActivities = forceResizable;
12881            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12882            if (supportsMultiWindow || forceResizable) {
12883                mSupportsMultiWindow = true;
12884                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12885                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12886            } else {
12887                mSupportsMultiWindow = false;
12888                mSupportsFreeformWindowManagement = false;
12889                mSupportsPictureInPicture = false;
12890            }
12891            // This happens before any activities are started, so we can
12892            // change mConfiguration in-place.
12893            updateConfigurationLocked(configuration, null, true);
12894            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12895                    "Initial config: " + mConfiguration);
12896
12897            // Load resources only after the current configuration has been set.
12898            final Resources res = mContext.getResources();
12899            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12900            mThumbnailWidth = res.getDimensionPixelSize(
12901                    com.android.internal.R.dimen.thumbnail_width);
12902            mThumbnailHeight = res.getDimensionPixelSize(
12903                    com.android.internal.R.dimen.thumbnail_height);
12904            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12905                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12906            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12907                    com.android.internal.R.string.config_appsNotReportingCrashes));
12908            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12909                mFullscreenThumbnailScale = (float) res
12910                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12911                    (float) mConfiguration.screenWidthDp;
12912            } else {
12913                mFullscreenThumbnailScale = res.getFraction(
12914                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12915            }
12916        }
12917    }
12918
12919    public boolean testIsSystemReady() {
12920        // no need to synchronize(this) just to read & return the value
12921        return mSystemReady;
12922    }
12923
12924    public void systemReady(final Runnable goingCallback) {
12925        synchronized(this) {
12926            if (mSystemReady) {
12927                // If we're done calling all the receivers, run the next "boot phase" passed in
12928                // by the SystemServer
12929                if (goingCallback != null) {
12930                    goingCallback.run();
12931                }
12932                return;
12933            }
12934
12935            mLocalDeviceIdleController
12936                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12937
12938            // Make sure we have the current profile info, since it is needed for security checks.
12939            mUserController.onSystemReady();
12940            mRecentTasks.onSystemReadyLocked();
12941            mAppOpsService.systemReady();
12942            mSystemReady = true;
12943        }
12944
12945        ArrayList<ProcessRecord> procsToKill = null;
12946        synchronized(mPidsSelfLocked) {
12947            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12948                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12949                if (!isAllowedWhileBooting(proc.info)){
12950                    if (procsToKill == null) {
12951                        procsToKill = new ArrayList<ProcessRecord>();
12952                    }
12953                    procsToKill.add(proc);
12954                }
12955            }
12956        }
12957
12958        synchronized(this) {
12959            if (procsToKill != null) {
12960                for (int i=procsToKill.size()-1; i>=0; i--) {
12961                    ProcessRecord proc = procsToKill.get(i);
12962                    Slog.i(TAG, "Removing system update proc: " + proc);
12963                    removeProcessLocked(proc, true, false, "system update done");
12964                }
12965            }
12966
12967            // Now that we have cleaned up any update processes, we
12968            // are ready to start launching real processes and know that
12969            // we won't trample on them any more.
12970            mProcessesReady = true;
12971        }
12972
12973        Slog.i(TAG, "System now ready");
12974        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12975            SystemClock.uptimeMillis());
12976
12977        synchronized(this) {
12978            // Make sure we have no pre-ready processes sitting around.
12979
12980            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12981                ResolveInfo ri = mContext.getPackageManager()
12982                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12983                                STOCK_PM_FLAGS);
12984                CharSequence errorMsg = null;
12985                if (ri != null) {
12986                    ActivityInfo ai = ri.activityInfo;
12987                    ApplicationInfo app = ai.applicationInfo;
12988                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12989                        mTopAction = Intent.ACTION_FACTORY_TEST;
12990                        mTopData = null;
12991                        mTopComponent = new ComponentName(app.packageName,
12992                                ai.name);
12993                    } else {
12994                        errorMsg = mContext.getResources().getText(
12995                                com.android.internal.R.string.factorytest_not_system);
12996                    }
12997                } else {
12998                    errorMsg = mContext.getResources().getText(
12999                            com.android.internal.R.string.factorytest_no_action);
13000                }
13001                if (errorMsg != null) {
13002                    mTopAction = null;
13003                    mTopData = null;
13004                    mTopComponent = null;
13005                    Message msg = Message.obtain();
13006                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13007                    msg.getData().putCharSequence("msg", errorMsg);
13008                    mUiHandler.sendMessage(msg);
13009                }
13010            }
13011        }
13012
13013        retrieveSettings();
13014        final int currentUserId;
13015        synchronized (this) {
13016            currentUserId = mUserController.getCurrentUserIdLocked();
13017            readGrantedUriPermissionsLocked();
13018        }
13019
13020        if (goingCallback != null) goingCallback.run();
13021
13022        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13023                Integer.toString(currentUserId), currentUserId);
13024        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13025                Integer.toString(currentUserId), currentUserId);
13026        mSystemServiceManager.startUser(currentUserId);
13027
13028        synchronized (this) {
13029            // Only start up encryption-aware persistent apps; once user is
13030            // unlocked we'll come back around and start unaware apps
13031            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13032
13033            // Start up initial activity.
13034            mBooting = true;
13035            // Enable home activity for system user, so that the system can always boot
13036            if (UserManager.isSplitSystemUser()) {
13037                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13038                try {
13039                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13040                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13041                            UserHandle.USER_SYSTEM);
13042                } catch (RemoteException e) {
13043                    throw e.rethrowAsRuntimeException();
13044                }
13045            }
13046            startHomeActivityLocked(currentUserId, "systemReady");
13047
13048            try {
13049                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13050                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13051                            + " data partition or your device will be unstable.");
13052                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13053                }
13054            } catch (RemoteException e) {
13055            }
13056
13057            if (!Build.isBuildConsistent()) {
13058                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13059                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13060            }
13061
13062            long ident = Binder.clearCallingIdentity();
13063            try {
13064                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13065                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13066                        | Intent.FLAG_RECEIVER_FOREGROUND);
13067                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13068                broadcastIntentLocked(null, null, intent,
13069                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13070                        null, false, false, MY_PID, Process.SYSTEM_UID,
13071                        currentUserId);
13072                intent = new Intent(Intent.ACTION_USER_STARTING);
13073                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13074                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13075                broadcastIntentLocked(null, null, intent,
13076                        null, new IIntentReceiver.Stub() {
13077                            @Override
13078                            public void performReceive(Intent intent, int resultCode, String data,
13079                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13080                                    throws RemoteException {
13081                            }
13082                        }, 0, null, null,
13083                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13084                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13085            } catch (Throwable t) {
13086                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13087            } finally {
13088                Binder.restoreCallingIdentity(ident);
13089            }
13090            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13091            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13092        }
13093    }
13094
13095    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13096        synchronized (this) {
13097            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13098        }
13099    }
13100
13101    void skipCurrentReceiverLocked(ProcessRecord app) {
13102        for (BroadcastQueue queue : mBroadcastQueues) {
13103            queue.skipCurrentReceiverLocked(app);
13104        }
13105    }
13106
13107    /**
13108     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13109     * The application process will exit immediately after this call returns.
13110     * @param app object of the crashing app, null for the system server
13111     * @param crashInfo describing the exception
13112     */
13113    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13114        ProcessRecord r = findAppProcess(app, "Crash");
13115        final String processName = app == null ? "system_server"
13116                : (r == null ? "unknown" : r.processName);
13117
13118        handleApplicationCrashInner("crash", r, processName, crashInfo);
13119    }
13120
13121    /* Native crash reporting uses this inner version because it needs to be somewhat
13122     * decoupled from the AM-managed cleanup lifecycle
13123     */
13124    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13125            ApplicationErrorReport.CrashInfo crashInfo) {
13126        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13127                UserHandle.getUserId(Binder.getCallingUid()), processName,
13128                r == null ? -1 : r.info.flags,
13129                crashInfo.exceptionClassName,
13130                crashInfo.exceptionMessage,
13131                crashInfo.throwFileName,
13132                crashInfo.throwLineNumber);
13133
13134        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13135
13136        mAppErrors.crashApplication(r, crashInfo);
13137    }
13138
13139    public void handleApplicationStrictModeViolation(
13140            IBinder app,
13141            int violationMask,
13142            StrictMode.ViolationInfo info) {
13143        ProcessRecord r = findAppProcess(app, "StrictMode");
13144        if (r == null) {
13145            return;
13146        }
13147
13148        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13149            Integer stackFingerprint = info.hashCode();
13150            boolean logIt = true;
13151            synchronized (mAlreadyLoggedViolatedStacks) {
13152                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13153                    logIt = false;
13154                    // TODO: sub-sample into EventLog for these, with
13155                    // the info.durationMillis?  Then we'd get
13156                    // the relative pain numbers, without logging all
13157                    // the stack traces repeatedly.  We'd want to do
13158                    // likewise in the client code, which also does
13159                    // dup suppression, before the Binder call.
13160                } else {
13161                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13162                        mAlreadyLoggedViolatedStacks.clear();
13163                    }
13164                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13165                }
13166            }
13167            if (logIt) {
13168                logStrictModeViolationToDropBox(r, info);
13169            }
13170        }
13171
13172        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13173            AppErrorResult result = new AppErrorResult();
13174            synchronized (this) {
13175                final long origId = Binder.clearCallingIdentity();
13176
13177                Message msg = Message.obtain();
13178                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13179                HashMap<String, Object> data = new HashMap<String, Object>();
13180                data.put("result", result);
13181                data.put("app", r);
13182                data.put("violationMask", violationMask);
13183                data.put("info", info);
13184                msg.obj = data;
13185                mUiHandler.sendMessage(msg);
13186
13187                Binder.restoreCallingIdentity(origId);
13188            }
13189            int res = result.get();
13190            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13191        }
13192    }
13193
13194    // Depending on the policy in effect, there could be a bunch of
13195    // these in quick succession so we try to batch these together to
13196    // minimize disk writes, number of dropbox entries, and maximize
13197    // compression, by having more fewer, larger records.
13198    private void logStrictModeViolationToDropBox(
13199            ProcessRecord process,
13200            StrictMode.ViolationInfo info) {
13201        if (info == null) {
13202            return;
13203        }
13204        final boolean isSystemApp = process == null ||
13205                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13206                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13207        final String processName = process == null ? "unknown" : process.processName;
13208        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13209        final DropBoxManager dbox = (DropBoxManager)
13210                mContext.getSystemService(Context.DROPBOX_SERVICE);
13211
13212        // Exit early if the dropbox isn't configured to accept this report type.
13213        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13214
13215        boolean bufferWasEmpty;
13216        boolean needsFlush;
13217        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13218        synchronized (sb) {
13219            bufferWasEmpty = sb.length() == 0;
13220            appendDropBoxProcessHeaders(process, processName, sb);
13221            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13222            sb.append("System-App: ").append(isSystemApp).append("\n");
13223            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13224            if (info.violationNumThisLoop != 0) {
13225                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13226            }
13227            if (info.numAnimationsRunning != 0) {
13228                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13229            }
13230            if (info.broadcastIntentAction != null) {
13231                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13232            }
13233            if (info.durationMillis != -1) {
13234                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13235            }
13236            if (info.numInstances != -1) {
13237                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13238            }
13239            if (info.tags != null) {
13240                for (String tag : info.tags) {
13241                    sb.append("Span-Tag: ").append(tag).append("\n");
13242                }
13243            }
13244            sb.append("\n");
13245            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13246                sb.append(info.crashInfo.stackTrace);
13247                sb.append("\n");
13248            }
13249            if (info.message != null) {
13250                sb.append(info.message);
13251                sb.append("\n");
13252            }
13253
13254            // Only buffer up to ~64k.  Various logging bits truncate
13255            // things at 128k.
13256            needsFlush = (sb.length() > 64 * 1024);
13257        }
13258
13259        // Flush immediately if the buffer's grown too large, or this
13260        // is a non-system app.  Non-system apps are isolated with a
13261        // different tag & policy and not batched.
13262        //
13263        // Batching is useful during internal testing with
13264        // StrictMode settings turned up high.  Without batching,
13265        // thousands of separate files could be created on boot.
13266        if (!isSystemApp || needsFlush) {
13267            new Thread("Error dump: " + dropboxTag) {
13268                @Override
13269                public void run() {
13270                    String report;
13271                    synchronized (sb) {
13272                        report = sb.toString();
13273                        sb.delete(0, sb.length());
13274                        sb.trimToSize();
13275                    }
13276                    if (report.length() != 0) {
13277                        dbox.addText(dropboxTag, report);
13278                    }
13279                }
13280            }.start();
13281            return;
13282        }
13283
13284        // System app batching:
13285        if (!bufferWasEmpty) {
13286            // An existing dropbox-writing thread is outstanding, so
13287            // we don't need to start it up.  The existing thread will
13288            // catch the buffer appends we just did.
13289            return;
13290        }
13291
13292        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13293        // (After this point, we shouldn't access AMS internal data structures.)
13294        new Thread("Error dump: " + dropboxTag) {
13295            @Override
13296            public void run() {
13297                // 5 second sleep to let stacks arrive and be batched together
13298                try {
13299                    Thread.sleep(5000);  // 5 seconds
13300                } catch (InterruptedException e) {}
13301
13302                String errorReport;
13303                synchronized (mStrictModeBuffer) {
13304                    errorReport = mStrictModeBuffer.toString();
13305                    if (errorReport.length() == 0) {
13306                        return;
13307                    }
13308                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13309                    mStrictModeBuffer.trimToSize();
13310                }
13311                dbox.addText(dropboxTag, errorReport);
13312            }
13313        }.start();
13314    }
13315
13316    /**
13317     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13318     * @param app object of the crashing app, null for the system server
13319     * @param tag reported by the caller
13320     * @param system whether this wtf is coming from the system
13321     * @param crashInfo describing the context of the error
13322     * @return true if the process should exit immediately (WTF is fatal)
13323     */
13324    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13325            final ApplicationErrorReport.CrashInfo crashInfo) {
13326        final int callingUid = Binder.getCallingUid();
13327        final int callingPid = Binder.getCallingPid();
13328
13329        if (system) {
13330            // If this is coming from the system, we could very well have low-level
13331            // system locks held, so we want to do this all asynchronously.  And we
13332            // never want this to become fatal, so there is that too.
13333            mHandler.post(new Runnable() {
13334                @Override public void run() {
13335                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13336                }
13337            });
13338            return false;
13339        }
13340
13341        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13342                crashInfo);
13343
13344        if (r != null && r.pid != Process.myPid() &&
13345                Settings.Global.getInt(mContext.getContentResolver(),
13346                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13347            mAppErrors.crashApplication(r, crashInfo);
13348            return true;
13349        } else {
13350            return false;
13351        }
13352    }
13353
13354    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13355            final ApplicationErrorReport.CrashInfo crashInfo) {
13356        final ProcessRecord r = findAppProcess(app, "WTF");
13357        final String processName = app == null ? "system_server"
13358                : (r == null ? "unknown" : r.processName);
13359
13360        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13361                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13362
13363        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13364
13365        return r;
13366    }
13367
13368    /**
13369     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13370     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13371     */
13372    private ProcessRecord findAppProcess(IBinder app, String reason) {
13373        if (app == null) {
13374            return null;
13375        }
13376
13377        synchronized (this) {
13378            final int NP = mProcessNames.getMap().size();
13379            for (int ip=0; ip<NP; ip++) {
13380                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13381                final int NA = apps.size();
13382                for (int ia=0; ia<NA; ia++) {
13383                    ProcessRecord p = apps.valueAt(ia);
13384                    if (p.thread != null && p.thread.asBinder() == app) {
13385                        return p;
13386                    }
13387                }
13388            }
13389
13390            Slog.w(TAG, "Can't find mystery application for " + reason
13391                    + " from pid=" + Binder.getCallingPid()
13392                    + " uid=" + Binder.getCallingUid() + ": " + app);
13393            return null;
13394        }
13395    }
13396
13397    /**
13398     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13399     * to append various headers to the dropbox log text.
13400     */
13401    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13402            StringBuilder sb) {
13403        // Watchdog thread ends up invoking this function (with
13404        // a null ProcessRecord) to add the stack file to dropbox.
13405        // Do not acquire a lock on this (am) in such cases, as it
13406        // could cause a potential deadlock, if and when watchdog
13407        // is invoked due to unavailability of lock on am and it
13408        // would prevent watchdog from killing system_server.
13409        if (process == null) {
13410            sb.append("Process: ").append(processName).append("\n");
13411            return;
13412        }
13413        // Note: ProcessRecord 'process' is guarded by the service
13414        // instance.  (notably process.pkgList, which could otherwise change
13415        // concurrently during execution of this method)
13416        synchronized (this) {
13417            sb.append("Process: ").append(processName).append("\n");
13418            int flags = process.info.flags;
13419            IPackageManager pm = AppGlobals.getPackageManager();
13420            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13421            for (int ip=0; ip<process.pkgList.size(); ip++) {
13422                String pkg = process.pkgList.keyAt(ip);
13423                sb.append("Package: ").append(pkg);
13424                try {
13425                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13426                    if (pi != null) {
13427                        sb.append(" v").append(pi.versionCode);
13428                        if (pi.versionName != null) {
13429                            sb.append(" (").append(pi.versionName).append(")");
13430                        }
13431                    }
13432                } catch (RemoteException e) {
13433                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13434                }
13435                sb.append("\n");
13436            }
13437        }
13438    }
13439
13440    private static String processClass(ProcessRecord process) {
13441        if (process == null || process.pid == MY_PID) {
13442            return "system_server";
13443        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13444            return "system_app";
13445        } else {
13446            return "data_app";
13447        }
13448    }
13449
13450    private volatile long mWtfClusterStart;
13451    private volatile int mWtfClusterCount;
13452
13453    /**
13454     * Write a description of an error (crash, WTF, ANR) to the drop box.
13455     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13456     * @param process which caused the error, null means the system server
13457     * @param activity which triggered the error, null if unknown
13458     * @param parent activity related to the error, null if unknown
13459     * @param subject line related to the error, null if absent
13460     * @param report in long form describing the error, null if absent
13461     * @param logFile to include in the report, null if none
13462     * @param crashInfo giving an application stack trace, null if absent
13463     */
13464    public void addErrorToDropBox(String eventType,
13465            ProcessRecord process, String processName, ActivityRecord activity,
13466            ActivityRecord parent, String subject,
13467            final String report, final File logFile,
13468            final ApplicationErrorReport.CrashInfo crashInfo) {
13469        // NOTE -- this must never acquire the ActivityManagerService lock,
13470        // otherwise the watchdog may be prevented from resetting the system.
13471
13472        final String dropboxTag = processClass(process) + "_" + eventType;
13473        final DropBoxManager dbox = (DropBoxManager)
13474                mContext.getSystemService(Context.DROPBOX_SERVICE);
13475
13476        // Exit early if the dropbox isn't configured to accept this report type.
13477        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13478
13479        // Rate-limit how often we're willing to do the heavy lifting below to
13480        // collect and record logs; currently 5 logs per 10 second period.
13481        final long now = SystemClock.elapsedRealtime();
13482        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13483            mWtfClusterStart = now;
13484            mWtfClusterCount = 1;
13485        } else {
13486            if (mWtfClusterCount++ >= 5) return;
13487        }
13488
13489        final StringBuilder sb = new StringBuilder(1024);
13490        appendDropBoxProcessHeaders(process, processName, sb);
13491        if (process != null) {
13492            sb.append("Foreground: ")
13493                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13494                    .append("\n");
13495        }
13496        if (activity != null) {
13497            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13498        }
13499        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13500            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13501        }
13502        if (parent != null && parent != activity) {
13503            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13504        }
13505        if (subject != null) {
13506            sb.append("Subject: ").append(subject).append("\n");
13507        }
13508        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13509        if (Debug.isDebuggerConnected()) {
13510            sb.append("Debugger: Connected\n");
13511        }
13512        sb.append("\n");
13513
13514        // Do the rest in a worker thread to avoid blocking the caller on I/O
13515        // (After this point, we shouldn't access AMS internal data structures.)
13516        Thread worker = new Thread("Error dump: " + dropboxTag) {
13517            @Override
13518            public void run() {
13519                if (report != null) {
13520                    sb.append(report);
13521                }
13522                if (logFile != null) {
13523                    try {
13524                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13525                                    "\n\n[[TRUNCATED]]"));
13526                    } catch (IOException e) {
13527                        Slog.e(TAG, "Error reading " + logFile, e);
13528                    }
13529                }
13530                if (crashInfo != null && crashInfo.stackTrace != null) {
13531                    sb.append(crashInfo.stackTrace);
13532                }
13533
13534                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13535                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13536                if (lines > 0) {
13537                    sb.append("\n");
13538
13539                    // Merge several logcat streams, and take the last N lines
13540                    InputStreamReader input = null;
13541                    try {
13542                        java.lang.Process logcat = new ProcessBuilder(
13543                                "/system/bin/timeout", "-k", "15s", "10s",
13544                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13545                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13546                                        .redirectErrorStream(true).start();
13547
13548                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13549                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13550                        input = new InputStreamReader(logcat.getInputStream());
13551
13552                        int num;
13553                        char[] buf = new char[8192];
13554                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13555                    } catch (IOException e) {
13556                        Slog.e(TAG, "Error running logcat", e);
13557                    } finally {
13558                        if (input != null) try { input.close(); } catch (IOException e) {}
13559                    }
13560                }
13561
13562                dbox.addText(dropboxTag, sb.toString());
13563            }
13564        };
13565
13566        if (process == null) {
13567            // If process is null, we are being called from some internal code
13568            // and may be about to die -- run this synchronously.
13569            worker.run();
13570        } else {
13571            worker.start();
13572        }
13573    }
13574
13575    @Override
13576    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13577        enforceNotIsolatedCaller("getProcessesInErrorState");
13578        // assume our apps are happy - lazy create the list
13579        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13580
13581        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13582                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13583        int userId = UserHandle.getUserId(Binder.getCallingUid());
13584
13585        synchronized (this) {
13586
13587            // iterate across all processes
13588            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13589                ProcessRecord app = mLruProcesses.get(i);
13590                if (!allUsers && app.userId != userId) {
13591                    continue;
13592                }
13593                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13594                    // This one's in trouble, so we'll generate a report for it
13595                    // crashes are higher priority (in case there's a crash *and* an anr)
13596                    ActivityManager.ProcessErrorStateInfo report = null;
13597                    if (app.crashing) {
13598                        report = app.crashingReport;
13599                    } else if (app.notResponding) {
13600                        report = app.notRespondingReport;
13601                    }
13602
13603                    if (report != null) {
13604                        if (errList == null) {
13605                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13606                        }
13607                        errList.add(report);
13608                    } else {
13609                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13610                                " crashing = " + app.crashing +
13611                                " notResponding = " + app.notResponding);
13612                    }
13613                }
13614            }
13615        }
13616
13617        return errList;
13618    }
13619
13620    static int procStateToImportance(int procState, int memAdj,
13621            ActivityManager.RunningAppProcessInfo currApp) {
13622        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13623        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13624            currApp.lru = memAdj;
13625        } else {
13626            currApp.lru = 0;
13627        }
13628        return imp;
13629    }
13630
13631    private void fillInProcMemInfo(ProcessRecord app,
13632            ActivityManager.RunningAppProcessInfo outInfo) {
13633        outInfo.pid = app.pid;
13634        outInfo.uid = app.info.uid;
13635        if (mHeavyWeightProcess == app) {
13636            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13637        }
13638        if (app.persistent) {
13639            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13640        }
13641        if (app.activities.size() > 0) {
13642            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13643        }
13644        outInfo.lastTrimLevel = app.trimMemoryLevel;
13645        int adj = app.curAdj;
13646        int procState = app.curProcState;
13647        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13648        outInfo.importanceReasonCode = app.adjTypeCode;
13649        outInfo.processState = app.curProcState;
13650    }
13651
13652    @Override
13653    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13654        enforceNotIsolatedCaller("getRunningAppProcesses");
13655
13656        final int callingUid = Binder.getCallingUid();
13657
13658        // Lazy instantiation of list
13659        List<ActivityManager.RunningAppProcessInfo> runList = null;
13660        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13661                callingUid) == PackageManager.PERMISSION_GRANTED;
13662        final int userId = UserHandle.getUserId(callingUid);
13663        final boolean allUids = isGetTasksAllowed(
13664                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13665
13666        synchronized (this) {
13667            // Iterate across all processes
13668            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13669                ProcessRecord app = mLruProcesses.get(i);
13670                if ((!allUsers && app.userId != userId)
13671                        || (!allUids && app.uid != callingUid)) {
13672                    continue;
13673                }
13674                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13675                    // Generate process state info for running application
13676                    ActivityManager.RunningAppProcessInfo currApp =
13677                        new ActivityManager.RunningAppProcessInfo(app.processName,
13678                                app.pid, app.getPackageList());
13679                    fillInProcMemInfo(app, currApp);
13680                    if (app.adjSource instanceof ProcessRecord) {
13681                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13682                        currApp.importanceReasonImportance =
13683                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13684                                        app.adjSourceProcState);
13685                    } else if (app.adjSource instanceof ActivityRecord) {
13686                        ActivityRecord r = (ActivityRecord)app.adjSource;
13687                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13688                    }
13689                    if (app.adjTarget instanceof ComponentName) {
13690                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13691                    }
13692                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13693                    //        + " lru=" + currApp.lru);
13694                    if (runList == null) {
13695                        runList = new ArrayList<>();
13696                    }
13697                    runList.add(currApp);
13698                }
13699            }
13700        }
13701        return runList;
13702    }
13703
13704    @Override
13705    public List<ApplicationInfo> getRunningExternalApplications() {
13706        enforceNotIsolatedCaller("getRunningExternalApplications");
13707        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13708        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13709        if (runningApps != null && runningApps.size() > 0) {
13710            Set<String> extList = new HashSet<String>();
13711            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13712                if (app.pkgList != null) {
13713                    for (String pkg : app.pkgList) {
13714                        extList.add(pkg);
13715                    }
13716                }
13717            }
13718            IPackageManager pm = AppGlobals.getPackageManager();
13719            for (String pkg : extList) {
13720                try {
13721                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13722                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13723                        retList.add(info);
13724                    }
13725                } catch (RemoteException e) {
13726                }
13727            }
13728        }
13729        return retList;
13730    }
13731
13732    @Override
13733    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13734        enforceNotIsolatedCaller("getMyMemoryState");
13735        synchronized (this) {
13736            ProcessRecord proc;
13737            synchronized (mPidsSelfLocked) {
13738                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13739            }
13740            fillInProcMemInfo(proc, outInfo);
13741        }
13742    }
13743
13744    @Override
13745    public int getMemoryTrimLevel() {
13746        enforceNotIsolatedCaller("getMyMemoryState");
13747        synchronized (this) {
13748            return mLastMemoryLevel;
13749        }
13750    }
13751
13752    @Override
13753    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13754            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13755        (new ActivityManagerShellCommand(this, false)).exec(
13756                this, in, out, err, args, resultReceiver);
13757    }
13758
13759    @Override
13760    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13761        if (checkCallingPermission(android.Manifest.permission.DUMP)
13762                != PackageManager.PERMISSION_GRANTED) {
13763            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13764                    + Binder.getCallingPid()
13765                    + ", uid=" + Binder.getCallingUid()
13766                    + " without permission "
13767                    + android.Manifest.permission.DUMP);
13768            return;
13769        }
13770
13771        boolean dumpAll = false;
13772        boolean dumpClient = false;
13773        boolean dumpCheckin = false;
13774        boolean dumpCheckinFormat = false;
13775        String dumpPackage = null;
13776
13777        int opti = 0;
13778        while (opti < args.length) {
13779            String opt = args[opti];
13780            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13781                break;
13782            }
13783            opti++;
13784            if ("-a".equals(opt)) {
13785                dumpAll = true;
13786            } else if ("-c".equals(opt)) {
13787                dumpClient = true;
13788            } else if ("-p".equals(opt)) {
13789                if (opti < args.length) {
13790                    dumpPackage = args[opti];
13791                    opti++;
13792                } else {
13793                    pw.println("Error: -p option requires package argument");
13794                    return;
13795                }
13796                dumpClient = true;
13797            } else if ("--checkin".equals(opt)) {
13798                dumpCheckin = dumpCheckinFormat = true;
13799            } else if ("-C".equals(opt)) {
13800                dumpCheckinFormat = true;
13801            } else if ("-h".equals(opt)) {
13802                ActivityManagerShellCommand.dumpHelp(pw, true);
13803                return;
13804            } else {
13805                pw.println("Unknown argument: " + opt + "; use -h for help");
13806            }
13807        }
13808
13809        long origId = Binder.clearCallingIdentity();
13810        boolean more = false;
13811        // Is the caller requesting to dump a particular piece of data?
13812        if (opti < args.length) {
13813            String cmd = args[opti];
13814            opti++;
13815            if ("activities".equals(cmd) || "a".equals(cmd)) {
13816                synchronized (this) {
13817                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13818                }
13819            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13820                synchronized (this) {
13821                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13822                }
13823            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13824                String[] newArgs;
13825                String name;
13826                if (opti >= args.length) {
13827                    name = null;
13828                    newArgs = EMPTY_STRING_ARRAY;
13829                } else {
13830                    dumpPackage = args[opti];
13831                    opti++;
13832                    newArgs = new String[args.length - opti];
13833                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13834                            args.length - opti);
13835                }
13836                synchronized (this) {
13837                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13838                }
13839            } else if ("broadcast-stats".equals(cmd)) {
13840                String[] newArgs;
13841                String name;
13842                if (opti >= args.length) {
13843                    name = null;
13844                    newArgs = EMPTY_STRING_ARRAY;
13845                } else {
13846                    dumpPackage = args[opti];
13847                    opti++;
13848                    newArgs = new String[args.length - opti];
13849                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13850                            args.length - opti);
13851                }
13852                synchronized (this) {
13853                    dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13854                }
13855            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13856                String[] newArgs;
13857                String name;
13858                if (opti >= args.length) {
13859                    name = null;
13860                    newArgs = EMPTY_STRING_ARRAY;
13861                } else {
13862                    dumpPackage = args[opti];
13863                    opti++;
13864                    newArgs = new String[args.length - opti];
13865                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13866                            args.length - opti);
13867                }
13868                synchronized (this) {
13869                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13870                }
13871            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13872                String[] newArgs;
13873                String name;
13874                if (opti >= args.length) {
13875                    name = null;
13876                    newArgs = EMPTY_STRING_ARRAY;
13877                } else {
13878                    dumpPackage = args[opti];
13879                    opti++;
13880                    newArgs = new String[args.length - opti];
13881                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13882                            args.length - opti);
13883                }
13884                synchronized (this) {
13885                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13886                }
13887            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13888                synchronized (this) {
13889                    dumpOomLocked(fd, pw, args, opti, true);
13890                }
13891            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13892                synchronized (this) {
13893                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13894                }
13895            } else if ("provider".equals(cmd)) {
13896                String[] newArgs;
13897                String name;
13898                if (opti >= args.length) {
13899                    name = null;
13900                    newArgs = EMPTY_STRING_ARRAY;
13901                } else {
13902                    name = args[opti];
13903                    opti++;
13904                    newArgs = new String[args.length - opti];
13905                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13906                }
13907                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13908                    pw.println("No providers match: " + name);
13909                    pw.println("Use -h for help.");
13910                }
13911            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13912                synchronized (this) {
13913                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13914                }
13915            } else if ("service".equals(cmd)) {
13916                String[] newArgs;
13917                String name;
13918                if (opti >= args.length) {
13919                    name = null;
13920                    newArgs = EMPTY_STRING_ARRAY;
13921                } else {
13922                    name = args[opti];
13923                    opti++;
13924                    newArgs = new String[args.length - opti];
13925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13926                            args.length - opti);
13927                }
13928                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13929                    pw.println("No services match: " + name);
13930                    pw.println("Use -h for help.");
13931                }
13932            } else if ("package".equals(cmd)) {
13933                String[] newArgs;
13934                if (opti >= args.length) {
13935                    pw.println("package: no package name specified");
13936                    pw.println("Use -h for help.");
13937                } else {
13938                    dumpPackage = args[opti];
13939                    opti++;
13940                    newArgs = new String[args.length - opti];
13941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13942                            args.length - opti);
13943                    args = newArgs;
13944                    opti = 0;
13945                    more = true;
13946                }
13947            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13948                synchronized (this) {
13949                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13950                }
13951            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13952                if (dumpClient) {
13953                    ActiveServices.ServiceDumper dumper;
13954                    synchronized (this) {
13955                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13956                                dumpPackage);
13957                    }
13958                    dumper.dumpWithClient();
13959                } else {
13960                    synchronized (this) {
13961                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13962                                dumpPackage).dumpLocked();
13963                    }
13964                }
13965            } else if ("locks".equals(cmd)) {
13966                LockGuard.dump(fd, pw, args);
13967            } else {
13968                // Dumping a single activity?
13969                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13970                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13971                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13972                    if (res < 0) {
13973                        pw.println("Bad activity command, or no activities match: " + cmd);
13974                        pw.println("Use -h for help.");
13975                    }
13976                }
13977            }
13978            if (!more) {
13979                Binder.restoreCallingIdentity(origId);
13980                return;
13981            }
13982        }
13983
13984        // No piece of data specified, dump everything.
13985        if (dumpCheckinFormat) {
13986            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
13987        } else if (dumpClient) {
13988            ActiveServices.ServiceDumper sdumper;
13989            synchronized (this) {
13990                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13991                pw.println();
13992                if (dumpAll) {
13993                    pw.println("-------------------------------------------------------------------------------");
13994                }
13995                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13996                pw.println();
13997                if (dumpAll) {
13998                    pw.println("-------------------------------------------------------------------------------");
13999                }
14000                if (dumpAll || dumpPackage != null) {
14001                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14002                    pw.println();
14003                    if (dumpAll) {
14004                        pw.println("-------------------------------------------------------------------------------");
14005                    }
14006                }
14007                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14008                pw.println();
14009                if (dumpAll) {
14010                    pw.println("-------------------------------------------------------------------------------");
14011                }
14012                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14013                pw.println();
14014                if (dumpAll) {
14015                    pw.println("-------------------------------------------------------------------------------");
14016                }
14017                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14018                        dumpPackage);
14019            }
14020            sdumper.dumpWithClient();
14021            pw.println();
14022            synchronized (this) {
14023                if (dumpAll) {
14024                    pw.println("-------------------------------------------------------------------------------");
14025                }
14026                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14027                pw.println();
14028                if (dumpAll) {
14029                    pw.println("-------------------------------------------------------------------------------");
14030                }
14031                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14032                if (mAssociations.size() > 0) {
14033                    pw.println();
14034                    if (dumpAll) {
14035                        pw.println("-------------------------------------------------------------------------------");
14036                    }
14037                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14038                }
14039                pw.println();
14040                if (dumpAll) {
14041                    pw.println("-------------------------------------------------------------------------------");
14042                }
14043                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14044            }
14045
14046        } else {
14047            synchronized (this) {
14048                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14049                pw.println();
14050                if (dumpAll) {
14051                    pw.println("-------------------------------------------------------------------------------");
14052                }
14053                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14054                pw.println();
14055                if (dumpAll) {
14056                    pw.println("-------------------------------------------------------------------------------");
14057                }
14058                if (dumpAll || dumpPackage != null) {
14059                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14060                    pw.println();
14061                    if (dumpAll) {
14062                        pw.println("-------------------------------------------------------------------------------");
14063                    }
14064                }
14065                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14066                pw.println();
14067                if (dumpAll) {
14068                    pw.println("-------------------------------------------------------------------------------");
14069                }
14070                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14071                pw.println();
14072                if (dumpAll) {
14073                    pw.println("-------------------------------------------------------------------------------");
14074                }
14075                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14076                        .dumpLocked();
14077                pw.println();
14078                if (dumpAll) {
14079                    pw.println("-------------------------------------------------------------------------------");
14080                }
14081                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14082                pw.println();
14083                if (dumpAll) {
14084                    pw.println("-------------------------------------------------------------------------------");
14085                }
14086                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14087                if (mAssociations.size() > 0) {
14088                    pw.println();
14089                    if (dumpAll) {
14090                        pw.println("-------------------------------------------------------------------------------");
14091                    }
14092                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14093                }
14094                pw.println();
14095                if (dumpAll) {
14096                    pw.println("-------------------------------------------------------------------------------");
14097                }
14098                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14099            }
14100        }
14101        Binder.restoreCallingIdentity(origId);
14102    }
14103
14104    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14105            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14106        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14107
14108        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14109                dumpPackage);
14110        boolean needSep = printedAnything;
14111
14112        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14113                dumpPackage, needSep, "  mFocusedActivity: ");
14114        if (printed) {
14115            printedAnything = true;
14116            needSep = false;
14117        }
14118
14119        if (dumpPackage == null) {
14120            if (needSep) {
14121                pw.println();
14122            }
14123            needSep = true;
14124            printedAnything = true;
14125            mStackSupervisor.dump(pw, "  ");
14126        }
14127
14128        if (!printedAnything) {
14129            pw.println("  (nothing)");
14130        }
14131    }
14132
14133    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14134            int opti, boolean dumpAll, String dumpPackage) {
14135        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14136
14137        boolean printedAnything = false;
14138
14139        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14140            boolean printedHeader = false;
14141
14142            final int N = mRecentTasks.size();
14143            for (int i=0; i<N; i++) {
14144                TaskRecord tr = mRecentTasks.get(i);
14145                if (dumpPackage != null) {
14146                    if (tr.realActivity == null ||
14147                            !dumpPackage.equals(tr.realActivity)) {
14148                        continue;
14149                    }
14150                }
14151                if (!printedHeader) {
14152                    pw.println("  Recent tasks:");
14153                    printedHeader = true;
14154                    printedAnything = true;
14155                }
14156                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14157                        pw.println(tr);
14158                if (dumpAll) {
14159                    mRecentTasks.get(i).dump(pw, "    ");
14160                }
14161            }
14162        }
14163
14164        if (!printedAnything) {
14165            pw.println("  (nothing)");
14166        }
14167    }
14168
14169    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14170            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14171        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14172
14173        int dumpUid = 0;
14174        if (dumpPackage != null) {
14175            IPackageManager pm = AppGlobals.getPackageManager();
14176            try {
14177                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14178            } catch (RemoteException e) {
14179            }
14180        }
14181
14182        boolean printedAnything = false;
14183
14184        final long now = SystemClock.uptimeMillis();
14185
14186        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14187            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14188                    = mAssociations.valueAt(i1);
14189            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14190                SparseArray<ArrayMap<String, Association>> sourceUids
14191                        = targetComponents.valueAt(i2);
14192                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14193                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14194                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14195                        Association ass = sourceProcesses.valueAt(i4);
14196                        if (dumpPackage != null) {
14197                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14198                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14199                                continue;
14200                            }
14201                        }
14202                        printedAnything = true;
14203                        pw.print("  ");
14204                        pw.print(ass.mTargetProcess);
14205                        pw.print("/");
14206                        UserHandle.formatUid(pw, ass.mTargetUid);
14207                        pw.print(" <- ");
14208                        pw.print(ass.mSourceProcess);
14209                        pw.print("/");
14210                        UserHandle.formatUid(pw, ass.mSourceUid);
14211                        pw.println();
14212                        pw.print("    via ");
14213                        pw.print(ass.mTargetComponent.flattenToShortString());
14214                        pw.println();
14215                        pw.print("    ");
14216                        long dur = ass.mTime;
14217                        if (ass.mNesting > 0) {
14218                            dur += now - ass.mStartTime;
14219                        }
14220                        TimeUtils.formatDuration(dur, pw);
14221                        pw.print(" (");
14222                        pw.print(ass.mCount);
14223                        pw.print(" times)");
14224                        pw.print("  ");
14225                        for (int i=0; i<ass.mStateTimes.length; i++) {
14226                            long amt = ass.mStateTimes[i];
14227                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14228                                amt += now - ass.mLastStateUptime;
14229                            }
14230                            if (amt != 0) {
14231                                pw.print(" ");
14232                                pw.print(ProcessList.makeProcStateString(
14233                                            i + ActivityManager.MIN_PROCESS_STATE));
14234                                pw.print("=");
14235                                TimeUtils.formatDuration(amt, pw);
14236                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14237                                    pw.print("*");
14238                                }
14239                            }
14240                        }
14241                        pw.println();
14242                        if (ass.mNesting > 0) {
14243                            pw.print("    Currently active: ");
14244                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14245                            pw.println();
14246                        }
14247                    }
14248                }
14249            }
14250
14251        }
14252
14253        if (!printedAnything) {
14254            pw.println("  (nothing)");
14255        }
14256    }
14257
14258    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14259            String header, boolean needSep) {
14260        boolean printed = false;
14261        int whichAppId = -1;
14262        if (dumpPackage != null) {
14263            try {
14264                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14265                        dumpPackage, 0);
14266                whichAppId = UserHandle.getAppId(info.uid);
14267            } catch (NameNotFoundException e) {
14268                e.printStackTrace();
14269            }
14270        }
14271        for (int i=0; i<uids.size(); i++) {
14272            UidRecord uidRec = uids.valueAt(i);
14273            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14274                continue;
14275            }
14276            if (!printed) {
14277                printed = true;
14278                if (needSep) {
14279                    pw.println();
14280                }
14281                pw.print("  ");
14282                pw.println(header);
14283                needSep = true;
14284            }
14285            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14286            pw.print(": "); pw.println(uidRec);
14287        }
14288        return printed;
14289    }
14290
14291    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14292            int opti, boolean dumpAll, String dumpPackage) {
14293        boolean needSep = false;
14294        boolean printedAnything = false;
14295        int numPers = 0;
14296
14297        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14298
14299        if (dumpAll) {
14300            final int NP = mProcessNames.getMap().size();
14301            for (int ip=0; ip<NP; ip++) {
14302                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14303                final int NA = procs.size();
14304                for (int ia=0; ia<NA; ia++) {
14305                    ProcessRecord r = procs.valueAt(ia);
14306                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14307                        continue;
14308                    }
14309                    if (!needSep) {
14310                        pw.println("  All known processes:");
14311                        needSep = true;
14312                        printedAnything = true;
14313                    }
14314                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14315                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14316                        pw.print(" "); pw.println(r);
14317                    r.dump(pw, "    ");
14318                    if (r.persistent) {
14319                        numPers++;
14320                    }
14321                }
14322            }
14323        }
14324
14325        if (mIsolatedProcesses.size() > 0) {
14326            boolean printed = false;
14327            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14328                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14329                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14330                    continue;
14331                }
14332                if (!printed) {
14333                    if (needSep) {
14334                        pw.println();
14335                    }
14336                    pw.println("  Isolated process list (sorted by uid):");
14337                    printedAnything = true;
14338                    printed = true;
14339                    needSep = true;
14340                }
14341                pw.println(String.format("%sIsolated #%2d: %s",
14342                        "    ", i, r.toString()));
14343            }
14344        }
14345
14346        if (mActiveUids.size() > 0) {
14347            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14348                printedAnything = needSep = true;
14349            }
14350        }
14351        if (mValidateUids.size() > 0) {
14352            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14353                printedAnything = needSep = true;
14354            }
14355        }
14356
14357        if (mLruProcesses.size() > 0) {
14358            if (needSep) {
14359                pw.println();
14360            }
14361            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14362                    pw.print(" total, non-act at ");
14363                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14364                    pw.print(", non-svc at ");
14365                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14366                    pw.println("):");
14367            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14368            needSep = true;
14369            printedAnything = true;
14370        }
14371
14372        if (dumpAll || dumpPackage != null) {
14373            synchronized (mPidsSelfLocked) {
14374                boolean printed = false;
14375                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14376                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14377                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14378                        continue;
14379                    }
14380                    if (!printed) {
14381                        if (needSep) pw.println();
14382                        needSep = true;
14383                        pw.println("  PID mappings:");
14384                        printed = true;
14385                        printedAnything = true;
14386                    }
14387                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14388                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14389                }
14390            }
14391        }
14392
14393        if (mForegroundProcesses.size() > 0) {
14394            synchronized (mPidsSelfLocked) {
14395                boolean printed = false;
14396                for (int i=0; i<mForegroundProcesses.size(); i++) {
14397                    ProcessRecord r = mPidsSelfLocked.get(
14398                            mForegroundProcesses.valueAt(i).pid);
14399                    if (dumpPackage != null && (r == null
14400                            || !r.pkgList.containsKey(dumpPackage))) {
14401                        continue;
14402                    }
14403                    if (!printed) {
14404                        if (needSep) pw.println();
14405                        needSep = true;
14406                        pw.println("  Foreground Processes:");
14407                        printed = true;
14408                        printedAnything = true;
14409                    }
14410                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14411                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14412                }
14413            }
14414        }
14415
14416        if (mPersistentStartingProcesses.size() > 0) {
14417            if (needSep) pw.println();
14418            needSep = true;
14419            printedAnything = true;
14420            pw.println("  Persisent processes that are starting:");
14421            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14422                    "Starting Norm", "Restarting PERS", dumpPackage);
14423        }
14424
14425        if (mRemovedProcesses.size() > 0) {
14426            if (needSep) pw.println();
14427            needSep = true;
14428            printedAnything = true;
14429            pw.println("  Processes that are being removed:");
14430            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14431                    "Removed Norm", "Removed PERS", dumpPackage);
14432        }
14433
14434        if (mProcessesOnHold.size() > 0) {
14435            if (needSep) pw.println();
14436            needSep = true;
14437            printedAnything = true;
14438            pw.println("  Processes that are on old until the system is ready:");
14439            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14440                    "OnHold Norm", "OnHold PERS", dumpPackage);
14441        }
14442
14443        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14444
14445        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14446        if (needSep) {
14447            printedAnything = true;
14448        }
14449
14450        if (dumpPackage == null) {
14451            pw.println();
14452            needSep = false;
14453            mUserController.dump(pw, dumpAll);
14454        }
14455        if (mHomeProcess != null && (dumpPackage == null
14456                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14457            if (needSep) {
14458                pw.println();
14459                needSep = false;
14460            }
14461            pw.println("  mHomeProcess: " + mHomeProcess);
14462        }
14463        if (mPreviousProcess != null && (dumpPackage == null
14464                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14465            if (needSep) {
14466                pw.println();
14467                needSep = false;
14468            }
14469            pw.println("  mPreviousProcess: " + mPreviousProcess);
14470        }
14471        if (dumpAll) {
14472            StringBuilder sb = new StringBuilder(128);
14473            sb.append("  mPreviousProcessVisibleTime: ");
14474            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14475            pw.println(sb);
14476        }
14477        if (mHeavyWeightProcess != null && (dumpPackage == null
14478                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14479            if (needSep) {
14480                pw.println();
14481                needSep = false;
14482            }
14483            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14484        }
14485        if (dumpPackage == null) {
14486            pw.println("  mConfiguration: " + mConfiguration);
14487        }
14488        if (dumpAll) {
14489            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14490            if (mCompatModePackages.getPackages().size() > 0) {
14491                boolean printed = false;
14492                for (Map.Entry<String, Integer> entry
14493                        : mCompatModePackages.getPackages().entrySet()) {
14494                    String pkg = entry.getKey();
14495                    int mode = entry.getValue();
14496                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14497                        continue;
14498                    }
14499                    if (!printed) {
14500                        pw.println("  mScreenCompatPackages:");
14501                        printed = true;
14502                    }
14503                    pw.print("    "); pw.print(pkg); pw.print(": ");
14504                            pw.print(mode); pw.println();
14505                }
14506            }
14507        }
14508        if (dumpPackage == null) {
14509            pw.println("  mWakefulness="
14510                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14511            pw.println("  mSleepTokens=" + mSleepTokens);
14512            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14513                    + lockScreenShownToString());
14514            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14515            if (mRunningVoice != null) {
14516                pw.println("  mRunningVoice=" + mRunningVoice);
14517                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14518            }
14519        }
14520        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14521                || mOrigWaitForDebugger) {
14522            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14523                    || dumpPackage.equals(mOrigDebugApp)) {
14524                if (needSep) {
14525                    pw.println();
14526                    needSep = false;
14527                }
14528                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14529                        + " mDebugTransient=" + mDebugTransient
14530                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14531            }
14532        }
14533        if (mCurAppTimeTracker != null) {
14534            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14535        }
14536        if (mMemWatchProcesses.getMap().size() > 0) {
14537            pw.println("  Mem watch processes:");
14538            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14539                    = mMemWatchProcesses.getMap();
14540            for (int i=0; i<procs.size(); i++) {
14541                final String proc = procs.keyAt(i);
14542                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14543                for (int j=0; j<uids.size(); j++) {
14544                    if (needSep) {
14545                        pw.println();
14546                        needSep = false;
14547                    }
14548                    StringBuilder sb = new StringBuilder();
14549                    sb.append("    ").append(proc).append('/');
14550                    UserHandle.formatUid(sb, uids.keyAt(j));
14551                    Pair<Long, String> val = uids.valueAt(j);
14552                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14553                    if (val.second != null) {
14554                        sb.append(", report to ").append(val.second);
14555                    }
14556                    pw.println(sb.toString());
14557                }
14558            }
14559            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14560            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14561            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14562                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14563        }
14564        if (mTrackAllocationApp != null) {
14565            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14566                if (needSep) {
14567                    pw.println();
14568                    needSep = false;
14569                }
14570                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14571            }
14572        }
14573        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14574                || mProfileFd != null) {
14575            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14576                if (needSep) {
14577                    pw.println();
14578                    needSep = false;
14579                }
14580                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14581                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14582                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14583                        + mAutoStopProfiler);
14584                pw.println("  mProfileType=" + mProfileType);
14585            }
14586        }
14587        if (mNativeDebuggingApp != null) {
14588            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14589                if (needSep) {
14590                    pw.println();
14591                    needSep = false;
14592                }
14593                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14594            }
14595        }
14596        if (dumpPackage == null) {
14597            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14598                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14599                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14600            }
14601            if (mController != null) {
14602                pw.println("  mController=" + mController
14603                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14604            }
14605            if (dumpAll) {
14606                pw.println("  Total persistent processes: " + numPers);
14607                pw.println("  mProcessesReady=" + mProcessesReady
14608                        + " mSystemReady=" + mSystemReady
14609                        + " mBooted=" + mBooted
14610                        + " mFactoryTest=" + mFactoryTest);
14611                pw.println("  mBooting=" + mBooting
14612                        + " mCallFinishBooting=" + mCallFinishBooting
14613                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14614                pw.print("  mLastPowerCheckRealtime=");
14615                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14616                        pw.println("");
14617                pw.print("  mLastPowerCheckUptime=");
14618                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14619                        pw.println("");
14620                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14621                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14622                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14623                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14624                        + " (" + mLruProcesses.size() + " total)"
14625                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14626                        + " mNumServiceProcs=" + mNumServiceProcs
14627                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14628                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14629                        + " mLastMemoryLevel=" + mLastMemoryLevel
14630                        + " mLastNumProcesses=" + mLastNumProcesses);
14631                long now = SystemClock.uptimeMillis();
14632                pw.print("  mLastIdleTime=");
14633                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14634                        pw.print(" mLowRamSinceLastIdle=");
14635                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14636                        pw.println();
14637            }
14638        }
14639
14640        if (!printedAnything) {
14641            pw.println("  (nothing)");
14642        }
14643    }
14644
14645    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14646            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14647        if (mProcessesToGc.size() > 0) {
14648            boolean printed = false;
14649            long now = SystemClock.uptimeMillis();
14650            for (int i=0; i<mProcessesToGc.size(); i++) {
14651                ProcessRecord proc = mProcessesToGc.get(i);
14652                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14653                    continue;
14654                }
14655                if (!printed) {
14656                    if (needSep) pw.println();
14657                    needSep = true;
14658                    pw.println("  Processes that are waiting to GC:");
14659                    printed = true;
14660                }
14661                pw.print("    Process "); pw.println(proc);
14662                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14663                        pw.print(", last gced=");
14664                        pw.print(now-proc.lastRequestedGc);
14665                        pw.print(" ms ago, last lowMem=");
14666                        pw.print(now-proc.lastLowMemory);
14667                        pw.println(" ms ago");
14668
14669            }
14670        }
14671        return needSep;
14672    }
14673
14674    void printOomLevel(PrintWriter pw, String name, int adj) {
14675        pw.print("    ");
14676        if (adj >= 0) {
14677            pw.print(' ');
14678            if (adj < 10) pw.print(' ');
14679        } else {
14680            if (adj > -10) pw.print(' ');
14681        }
14682        pw.print(adj);
14683        pw.print(": ");
14684        pw.print(name);
14685        pw.print(" (");
14686        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14687        pw.println(")");
14688    }
14689
14690    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14691            int opti, boolean dumpAll) {
14692        boolean needSep = false;
14693
14694        if (mLruProcesses.size() > 0) {
14695            if (needSep) pw.println();
14696            needSep = true;
14697            pw.println("  OOM levels:");
14698            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14699            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14700            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14701            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14702            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14703            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14704            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14705            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14706            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14707            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14708            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14709            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14710            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14711            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14712
14713            if (needSep) pw.println();
14714            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14715                    pw.print(" total, non-act at ");
14716                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14717                    pw.print(", non-svc at ");
14718                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14719                    pw.println("):");
14720            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14721            needSep = true;
14722        }
14723
14724        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14725
14726        pw.println();
14727        pw.println("  mHomeProcess: " + mHomeProcess);
14728        pw.println("  mPreviousProcess: " + mPreviousProcess);
14729        if (mHeavyWeightProcess != null) {
14730            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14731        }
14732
14733        return true;
14734    }
14735
14736    /**
14737     * There are three ways to call this:
14738     *  - no provider specified: dump all the providers
14739     *  - a flattened component name that matched an existing provider was specified as the
14740     *    first arg: dump that one provider
14741     *  - the first arg isn't the flattened component name of an existing provider:
14742     *    dump all providers whose component contains the first arg as a substring
14743     */
14744    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14745            int opti, boolean dumpAll) {
14746        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14747    }
14748
14749    static class ItemMatcher {
14750        ArrayList<ComponentName> components;
14751        ArrayList<String> strings;
14752        ArrayList<Integer> objects;
14753        boolean all;
14754
14755        ItemMatcher() {
14756            all = true;
14757        }
14758
14759        void build(String name) {
14760            ComponentName componentName = ComponentName.unflattenFromString(name);
14761            if (componentName != null) {
14762                if (components == null) {
14763                    components = new ArrayList<ComponentName>();
14764                }
14765                components.add(componentName);
14766                all = false;
14767            } else {
14768                int objectId = 0;
14769                // Not a '/' separated full component name; maybe an object ID?
14770                try {
14771                    objectId = Integer.parseInt(name, 16);
14772                    if (objects == null) {
14773                        objects = new ArrayList<Integer>();
14774                    }
14775                    objects.add(objectId);
14776                    all = false;
14777                } catch (RuntimeException e) {
14778                    // Not an integer; just do string match.
14779                    if (strings == null) {
14780                        strings = new ArrayList<String>();
14781                    }
14782                    strings.add(name);
14783                    all = false;
14784                }
14785            }
14786        }
14787
14788        int build(String[] args, int opti) {
14789            for (; opti<args.length; opti++) {
14790                String name = args[opti];
14791                if ("--".equals(name)) {
14792                    return opti+1;
14793                }
14794                build(name);
14795            }
14796            return opti;
14797        }
14798
14799        boolean match(Object object, ComponentName comp) {
14800            if (all) {
14801                return true;
14802            }
14803            if (components != null) {
14804                for (int i=0; i<components.size(); i++) {
14805                    if (components.get(i).equals(comp)) {
14806                        return true;
14807                    }
14808                }
14809            }
14810            if (objects != null) {
14811                for (int i=0; i<objects.size(); i++) {
14812                    if (System.identityHashCode(object) == objects.get(i)) {
14813                        return true;
14814                    }
14815                }
14816            }
14817            if (strings != null) {
14818                String flat = comp.flattenToString();
14819                for (int i=0; i<strings.size(); i++) {
14820                    if (flat.contains(strings.get(i))) {
14821                        return true;
14822                    }
14823                }
14824            }
14825            return false;
14826        }
14827    }
14828
14829    /**
14830     * There are three things that cmd can be:
14831     *  - a flattened component name that matches an existing activity
14832     *  - the cmd arg isn't the flattened component name of an existing activity:
14833     *    dump all activity whose component contains the cmd as a substring
14834     *  - A hex number of the ActivityRecord object instance.
14835     */
14836    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14837            int opti, boolean dumpAll) {
14838        ArrayList<ActivityRecord> activities;
14839
14840        synchronized (this) {
14841            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14842        }
14843
14844        if (activities.size() <= 0) {
14845            return false;
14846        }
14847
14848        String[] newArgs = new String[args.length - opti];
14849        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14850
14851        TaskRecord lastTask = null;
14852        boolean needSep = false;
14853        for (int i=activities.size()-1; i>=0; i--) {
14854            ActivityRecord r = activities.get(i);
14855            if (needSep) {
14856                pw.println();
14857            }
14858            needSep = true;
14859            synchronized (this) {
14860                if (lastTask != r.task) {
14861                    lastTask = r.task;
14862                    pw.print("TASK "); pw.print(lastTask.affinity);
14863                            pw.print(" id="); pw.println(lastTask.taskId);
14864                    if (dumpAll) {
14865                        lastTask.dump(pw, "  ");
14866                    }
14867                }
14868            }
14869            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14870        }
14871        return true;
14872    }
14873
14874    /**
14875     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14876     * there is a thread associated with the activity.
14877     */
14878    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14879            final ActivityRecord r, String[] args, boolean dumpAll) {
14880        String innerPrefix = prefix + "  ";
14881        synchronized (this) {
14882            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14883                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14884                    pw.print(" pid=");
14885                    if (r.app != null) pw.println(r.app.pid);
14886                    else pw.println("(not running)");
14887            if (dumpAll) {
14888                r.dump(pw, innerPrefix);
14889            }
14890        }
14891        if (r.app != null && r.app.thread != null) {
14892            // flush anything that is already in the PrintWriter since the thread is going
14893            // to write to the file descriptor directly
14894            pw.flush();
14895            try {
14896                TransferPipe tp = new TransferPipe();
14897                try {
14898                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14899                            r.appToken, innerPrefix, args);
14900                    tp.go(fd);
14901                } finally {
14902                    tp.kill();
14903                }
14904            } catch (IOException e) {
14905                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14906            } catch (RemoteException e) {
14907                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14908            }
14909        }
14910    }
14911
14912    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14913            int opti, boolean dumpAll, String dumpPackage) {
14914        boolean needSep = false;
14915        boolean onlyHistory = false;
14916        boolean printedAnything = false;
14917
14918        if ("history".equals(dumpPackage)) {
14919            if (opti < args.length && "-s".equals(args[opti])) {
14920                dumpAll = false;
14921            }
14922            onlyHistory = true;
14923            dumpPackage = null;
14924        }
14925
14926        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14927        if (!onlyHistory && dumpAll) {
14928            if (mRegisteredReceivers.size() > 0) {
14929                boolean printed = false;
14930                Iterator it = mRegisteredReceivers.values().iterator();
14931                while (it.hasNext()) {
14932                    ReceiverList r = (ReceiverList)it.next();
14933                    if (dumpPackage != null && (r.app == null ||
14934                            !dumpPackage.equals(r.app.info.packageName))) {
14935                        continue;
14936                    }
14937                    if (!printed) {
14938                        pw.println("  Registered Receivers:");
14939                        needSep = true;
14940                        printed = true;
14941                        printedAnything = true;
14942                    }
14943                    pw.print("  * "); pw.println(r);
14944                    r.dump(pw, "    ");
14945                }
14946            }
14947
14948            if (mReceiverResolver.dump(pw, needSep ?
14949                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14950                    "    ", dumpPackage, false, false)) {
14951                needSep = true;
14952                printedAnything = true;
14953            }
14954        }
14955
14956        for (BroadcastQueue q : mBroadcastQueues) {
14957            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14958            printedAnything |= needSep;
14959        }
14960
14961        needSep = true;
14962
14963        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14964            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14965                if (needSep) {
14966                    pw.println();
14967                }
14968                needSep = true;
14969                printedAnything = true;
14970                pw.print("  Sticky broadcasts for user ");
14971                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14972                StringBuilder sb = new StringBuilder(128);
14973                for (Map.Entry<String, ArrayList<Intent>> ent
14974                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14975                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14976                    if (dumpAll) {
14977                        pw.println(":");
14978                        ArrayList<Intent> intents = ent.getValue();
14979                        final int N = intents.size();
14980                        for (int i=0; i<N; i++) {
14981                            sb.setLength(0);
14982                            sb.append("    Intent: ");
14983                            intents.get(i).toShortString(sb, false, true, false, false);
14984                            pw.println(sb.toString());
14985                            Bundle bundle = intents.get(i).getExtras();
14986                            if (bundle != null) {
14987                                pw.print("      ");
14988                                pw.println(bundle.toString());
14989                            }
14990                        }
14991                    } else {
14992                        pw.println("");
14993                    }
14994                }
14995            }
14996        }
14997
14998        if (!onlyHistory && dumpAll) {
14999            pw.println();
15000            for (BroadcastQueue queue : mBroadcastQueues) {
15001                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15002                        + queue.mBroadcastsScheduled);
15003            }
15004            pw.println("  mHandler:");
15005            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15006            needSep = true;
15007            printedAnything = true;
15008        }
15009
15010        if (!printedAnything) {
15011            pw.println("  (nothing)");
15012        }
15013    }
15014
15015    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15016            int opti, boolean dumpAll, String dumpPackage) {
15017        if (mCurBroadcastStats == null) {
15018            return;
15019        }
15020
15021        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15022        final long now = SystemClock.elapsedRealtime();
15023        if (mLastBroadcastStats != null) {
15024            pw.print("  Last stats (from ");
15025            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15026            pw.print(" to ");
15027            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15028            pw.print(", ");
15029            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15030                    - mLastBroadcastStats.mStartUptime, pw);
15031            pw.println(" uptime):");
15032            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15033                pw.println("    (nothing)");
15034            }
15035            pw.println();
15036        }
15037        pw.print("  Current stats (from ");
15038        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15039        pw.print(" to now, ");
15040        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15041                - mCurBroadcastStats.mStartUptime, pw);
15042        pw.println(" uptime):");
15043        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15044            pw.println("    (nothing)");
15045        }
15046    }
15047
15048    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15049            int opti, boolean fullCheckin, String dumpPackage) {
15050        if (mCurBroadcastStats == null) {
15051            return;
15052        }
15053
15054        if (mLastBroadcastStats != null) {
15055            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15056            if (fullCheckin) {
15057                mLastBroadcastStats = null;
15058                return;
15059            }
15060        }
15061        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15062        if (fullCheckin) {
15063            mCurBroadcastStats = null;
15064        }
15065    }
15066
15067    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15068            int opti, boolean dumpAll, String dumpPackage) {
15069        boolean needSep;
15070        boolean printedAnything = false;
15071
15072        ItemMatcher matcher = new ItemMatcher();
15073        matcher.build(args, opti);
15074
15075        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15076
15077        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15078        printedAnything |= needSep;
15079
15080        if (mLaunchingProviders.size() > 0) {
15081            boolean printed = false;
15082            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15083                ContentProviderRecord r = mLaunchingProviders.get(i);
15084                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15085                    continue;
15086                }
15087                if (!printed) {
15088                    if (needSep) pw.println();
15089                    needSep = true;
15090                    pw.println("  Launching content providers:");
15091                    printed = true;
15092                    printedAnything = true;
15093                }
15094                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15095                        pw.println(r);
15096            }
15097        }
15098
15099        if (!printedAnything) {
15100            pw.println("  (nothing)");
15101        }
15102    }
15103
15104    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15105            int opti, boolean dumpAll, String dumpPackage) {
15106        boolean needSep = false;
15107        boolean printedAnything = false;
15108
15109        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15110
15111        if (mGrantedUriPermissions.size() > 0) {
15112            boolean printed = false;
15113            int dumpUid = -2;
15114            if (dumpPackage != null) {
15115                try {
15116                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15117                            MATCH_UNINSTALLED_PACKAGES, 0);
15118                } catch (NameNotFoundException e) {
15119                    dumpUid = -1;
15120                }
15121            }
15122            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15123                int uid = mGrantedUriPermissions.keyAt(i);
15124                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15125                    continue;
15126                }
15127                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15128                if (!printed) {
15129                    if (needSep) pw.println();
15130                    needSep = true;
15131                    pw.println("  Granted Uri Permissions:");
15132                    printed = true;
15133                    printedAnything = true;
15134                }
15135                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15136                for (UriPermission perm : perms.values()) {
15137                    pw.print("    "); pw.println(perm);
15138                    if (dumpAll) {
15139                        perm.dump(pw, "      ");
15140                    }
15141                }
15142            }
15143        }
15144
15145        if (!printedAnything) {
15146            pw.println("  (nothing)");
15147        }
15148    }
15149
15150    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15151            int opti, boolean dumpAll, String dumpPackage) {
15152        boolean printed = false;
15153
15154        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15155
15156        if (mIntentSenderRecords.size() > 0) {
15157            Iterator<WeakReference<PendingIntentRecord>> it
15158                    = mIntentSenderRecords.values().iterator();
15159            while (it.hasNext()) {
15160                WeakReference<PendingIntentRecord> ref = it.next();
15161                PendingIntentRecord rec = ref != null ? ref.get(): null;
15162                if (dumpPackage != null && (rec == null
15163                        || !dumpPackage.equals(rec.key.packageName))) {
15164                    continue;
15165                }
15166                printed = true;
15167                if (rec != null) {
15168                    pw.print("  * "); pw.println(rec);
15169                    if (dumpAll) {
15170                        rec.dump(pw, "    ");
15171                    }
15172                } else {
15173                    pw.print("  * "); pw.println(ref);
15174                }
15175            }
15176        }
15177
15178        if (!printed) {
15179            pw.println("  (nothing)");
15180        }
15181    }
15182
15183    private static final int dumpProcessList(PrintWriter pw,
15184            ActivityManagerService service, List list,
15185            String prefix, String normalLabel, String persistentLabel,
15186            String dumpPackage) {
15187        int numPers = 0;
15188        final int N = list.size()-1;
15189        for (int i=N; i>=0; i--) {
15190            ProcessRecord r = (ProcessRecord)list.get(i);
15191            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15192                continue;
15193            }
15194            pw.println(String.format("%s%s #%2d: %s",
15195                    prefix, (r.persistent ? persistentLabel : normalLabel),
15196                    i, r.toString()));
15197            if (r.persistent) {
15198                numPers++;
15199            }
15200        }
15201        return numPers;
15202    }
15203
15204    private static final boolean dumpProcessOomList(PrintWriter pw,
15205            ActivityManagerService service, List<ProcessRecord> origList,
15206            String prefix, String normalLabel, String persistentLabel,
15207            boolean inclDetails, String dumpPackage) {
15208
15209        ArrayList<Pair<ProcessRecord, Integer>> list
15210                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15211        for (int i=0; i<origList.size(); i++) {
15212            ProcessRecord r = origList.get(i);
15213            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15214                continue;
15215            }
15216            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15217        }
15218
15219        if (list.size() <= 0) {
15220            return false;
15221        }
15222
15223        Comparator<Pair<ProcessRecord, Integer>> comparator
15224                = new Comparator<Pair<ProcessRecord, Integer>>() {
15225            @Override
15226            public int compare(Pair<ProcessRecord, Integer> object1,
15227                    Pair<ProcessRecord, Integer> object2) {
15228                if (object1.first.setAdj != object2.first.setAdj) {
15229                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15230                }
15231                if (object1.first.setProcState != object2.first.setProcState) {
15232                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15233                }
15234                if (object1.second.intValue() != object2.second.intValue()) {
15235                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15236                }
15237                return 0;
15238            }
15239        };
15240
15241        Collections.sort(list, comparator);
15242
15243        final long curRealtime = SystemClock.elapsedRealtime();
15244        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15245        final long curUptime = SystemClock.uptimeMillis();
15246        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15247
15248        for (int i=list.size()-1; i>=0; i--) {
15249            ProcessRecord r = list.get(i).first;
15250            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15251            char schedGroup;
15252            switch (r.setSchedGroup) {
15253                case ProcessList.SCHED_GROUP_BACKGROUND:
15254                    schedGroup = 'B';
15255                    break;
15256                case ProcessList.SCHED_GROUP_DEFAULT:
15257                    schedGroup = 'F';
15258                    break;
15259                case ProcessList.SCHED_GROUP_TOP_APP:
15260                    schedGroup = 'T';
15261                    break;
15262                default:
15263                    schedGroup = '?';
15264                    break;
15265            }
15266            char foreground;
15267            if (r.foregroundActivities) {
15268                foreground = 'A';
15269            } else if (r.foregroundServices) {
15270                foreground = 'S';
15271            } else {
15272                foreground = ' ';
15273            }
15274            String procState = ProcessList.makeProcStateString(r.curProcState);
15275            pw.print(prefix);
15276            pw.print(r.persistent ? persistentLabel : normalLabel);
15277            pw.print(" #");
15278            int num = (origList.size()-1)-list.get(i).second;
15279            if (num < 10) pw.print(' ');
15280            pw.print(num);
15281            pw.print(": ");
15282            pw.print(oomAdj);
15283            pw.print(' ');
15284            pw.print(schedGroup);
15285            pw.print('/');
15286            pw.print(foreground);
15287            pw.print('/');
15288            pw.print(procState);
15289            pw.print(" trm:");
15290            if (r.trimMemoryLevel < 10) pw.print(' ');
15291            pw.print(r.trimMemoryLevel);
15292            pw.print(' ');
15293            pw.print(r.toShortString());
15294            pw.print(" (");
15295            pw.print(r.adjType);
15296            pw.println(')');
15297            if (r.adjSource != null || r.adjTarget != null) {
15298                pw.print(prefix);
15299                pw.print("    ");
15300                if (r.adjTarget instanceof ComponentName) {
15301                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15302                } else if (r.adjTarget != null) {
15303                    pw.print(r.adjTarget.toString());
15304                } else {
15305                    pw.print("{null}");
15306                }
15307                pw.print("<=");
15308                if (r.adjSource instanceof ProcessRecord) {
15309                    pw.print("Proc{");
15310                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15311                    pw.println("}");
15312                } else if (r.adjSource != null) {
15313                    pw.println(r.adjSource.toString());
15314                } else {
15315                    pw.println("{null}");
15316                }
15317            }
15318            if (inclDetails) {
15319                pw.print(prefix);
15320                pw.print("    ");
15321                pw.print("oom: max="); pw.print(r.maxAdj);
15322                pw.print(" curRaw="); pw.print(r.curRawAdj);
15323                pw.print(" setRaw="); pw.print(r.setRawAdj);
15324                pw.print(" cur="); pw.print(r.curAdj);
15325                pw.print(" set="); pw.println(r.setAdj);
15326                pw.print(prefix);
15327                pw.print("    ");
15328                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15329                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15330                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15331                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15332                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15333                pw.println();
15334                pw.print(prefix);
15335                pw.print("    ");
15336                pw.print("cached="); pw.print(r.cached);
15337                pw.print(" empty="); pw.print(r.empty);
15338                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15339
15340                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15341                    if (r.lastWakeTime != 0) {
15342                        long wtime;
15343                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15344                        synchronized (stats) {
15345                            wtime = stats.getProcessWakeTime(r.info.uid,
15346                                    r.pid, curRealtime);
15347                        }
15348                        long timeUsed = wtime - r.lastWakeTime;
15349                        pw.print(prefix);
15350                        pw.print("    ");
15351                        pw.print("keep awake over ");
15352                        TimeUtils.formatDuration(realtimeSince, pw);
15353                        pw.print(" used ");
15354                        TimeUtils.formatDuration(timeUsed, pw);
15355                        pw.print(" (");
15356                        pw.print((timeUsed*100)/realtimeSince);
15357                        pw.println("%)");
15358                    }
15359                    if (r.lastCpuTime != 0) {
15360                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15361                        pw.print(prefix);
15362                        pw.print("    ");
15363                        pw.print("run cpu over ");
15364                        TimeUtils.formatDuration(uptimeSince, pw);
15365                        pw.print(" used ");
15366                        TimeUtils.formatDuration(timeUsed, pw);
15367                        pw.print(" (");
15368                        pw.print((timeUsed*100)/uptimeSince);
15369                        pw.println("%)");
15370                    }
15371                }
15372            }
15373        }
15374        return true;
15375    }
15376
15377    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15378            String[] args) {
15379        ArrayList<ProcessRecord> procs;
15380        synchronized (this) {
15381            if (args != null && args.length > start
15382                    && args[start].charAt(0) != '-') {
15383                procs = new ArrayList<ProcessRecord>();
15384                int pid = -1;
15385                try {
15386                    pid = Integer.parseInt(args[start]);
15387                } catch (NumberFormatException e) {
15388                }
15389                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15390                    ProcessRecord proc = mLruProcesses.get(i);
15391                    if (proc.pid == pid) {
15392                        procs.add(proc);
15393                    } else if (allPkgs && proc.pkgList != null
15394                            && proc.pkgList.containsKey(args[start])) {
15395                        procs.add(proc);
15396                    } else if (proc.processName.equals(args[start])) {
15397                        procs.add(proc);
15398                    }
15399                }
15400                if (procs.size() <= 0) {
15401                    return null;
15402                }
15403            } else {
15404                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15405            }
15406        }
15407        return procs;
15408    }
15409
15410    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15411            PrintWriter pw, String[] args) {
15412        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15413        if (procs == null) {
15414            pw.println("No process found for: " + args[0]);
15415            return;
15416        }
15417
15418        long uptime = SystemClock.uptimeMillis();
15419        long realtime = SystemClock.elapsedRealtime();
15420        pw.println("Applications Graphics Acceleration Info:");
15421        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15422
15423        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15424            ProcessRecord r = procs.get(i);
15425            if (r.thread != null) {
15426                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15427                pw.flush();
15428                try {
15429                    TransferPipe tp = new TransferPipe();
15430                    try {
15431                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15432                        tp.go(fd);
15433                    } finally {
15434                        tp.kill();
15435                    }
15436                } catch (IOException e) {
15437                    pw.println("Failure while dumping the app: " + r);
15438                    pw.flush();
15439                } catch (RemoteException e) {
15440                    pw.println("Got a RemoteException while dumping the app " + r);
15441                    pw.flush();
15442                }
15443            }
15444        }
15445    }
15446
15447    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15448        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15449        if (procs == null) {
15450            pw.println("No process found for: " + args[0]);
15451            return;
15452        }
15453
15454        pw.println("Applications Database Info:");
15455
15456        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15457            ProcessRecord r = procs.get(i);
15458            if (r.thread != null) {
15459                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15460                pw.flush();
15461                try {
15462                    TransferPipe tp = new TransferPipe();
15463                    try {
15464                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15465                        tp.go(fd);
15466                    } finally {
15467                        tp.kill();
15468                    }
15469                } catch (IOException e) {
15470                    pw.println("Failure while dumping the app: " + r);
15471                    pw.flush();
15472                } catch (RemoteException e) {
15473                    pw.println("Got a RemoteException while dumping the app " + r);
15474                    pw.flush();
15475                }
15476            }
15477        }
15478    }
15479
15480    final static class MemItem {
15481        final boolean isProc;
15482        final String label;
15483        final String shortLabel;
15484        final long pss;
15485        final long swapPss;
15486        final int id;
15487        final boolean hasActivities;
15488        ArrayList<MemItem> subitems;
15489
15490        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15491                boolean _hasActivities) {
15492            isProc = true;
15493            label = _label;
15494            shortLabel = _shortLabel;
15495            pss = _pss;
15496            swapPss = _swapPss;
15497            id = _id;
15498            hasActivities = _hasActivities;
15499        }
15500
15501        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15502            isProc = false;
15503            label = _label;
15504            shortLabel = _shortLabel;
15505            pss = _pss;
15506            swapPss = _swapPss;
15507            id = _id;
15508            hasActivities = false;
15509        }
15510    }
15511
15512    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15513            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15514        if (sort && !isCompact) {
15515            Collections.sort(items, new Comparator<MemItem>() {
15516                @Override
15517                public int compare(MemItem lhs, MemItem rhs) {
15518                    if (lhs.pss < rhs.pss) {
15519                        return 1;
15520                    } else if (lhs.pss > rhs.pss) {
15521                        return -1;
15522                    }
15523                    return 0;
15524                }
15525            });
15526        }
15527
15528        for (int i=0; i<items.size(); i++) {
15529            MemItem mi = items.get(i);
15530            if (!isCompact) {
15531                if (dumpSwapPss) {
15532                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15533                            mi.label, stringifyKBSize(mi.swapPss));
15534                } else {
15535                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15536                }
15537            } else if (mi.isProc) {
15538                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15539                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15540                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15541                pw.println(mi.hasActivities ? ",a" : ",e");
15542            } else {
15543                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15544                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15545            }
15546            if (mi.subitems != null) {
15547                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15548                        true, isCompact, dumpSwapPss);
15549            }
15550        }
15551    }
15552
15553    // These are in KB.
15554    static final long[] DUMP_MEM_BUCKETS = new long[] {
15555        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15556        120*1024, 160*1024, 200*1024,
15557        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15558        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15559    };
15560
15561    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15562            boolean stackLike) {
15563        int start = label.lastIndexOf('.');
15564        if (start >= 0) start++;
15565        else start = 0;
15566        int end = label.length();
15567        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15568            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15569                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15570                out.append(bucket);
15571                out.append(stackLike ? "MB." : "MB ");
15572                out.append(label, start, end);
15573                return;
15574            }
15575        }
15576        out.append(memKB/1024);
15577        out.append(stackLike ? "MB." : "MB ");
15578        out.append(label, start, end);
15579    }
15580
15581    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15582            ProcessList.NATIVE_ADJ,
15583            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15584            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15585            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15586            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15587            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15588            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15589    };
15590    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15591            "Native",
15592            "System", "Persistent", "Persistent Service", "Foreground",
15593            "Visible", "Perceptible",
15594            "Heavy Weight", "Backup",
15595            "A Services", "Home",
15596            "Previous", "B Services", "Cached"
15597    };
15598    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15599            "native",
15600            "sys", "pers", "persvc", "fore",
15601            "vis", "percept",
15602            "heavy", "backup",
15603            "servicea", "home",
15604            "prev", "serviceb", "cached"
15605    };
15606
15607    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15608            long realtime, boolean isCheckinRequest, boolean isCompact) {
15609        if (isCompact) {
15610            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15611        }
15612        if (isCheckinRequest || isCompact) {
15613            // short checkin version
15614            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15615        } else {
15616            pw.println("Applications Memory Usage (in Kilobytes):");
15617            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15618        }
15619    }
15620
15621    private static final int KSM_SHARED = 0;
15622    private static final int KSM_SHARING = 1;
15623    private static final int KSM_UNSHARED = 2;
15624    private static final int KSM_VOLATILE = 3;
15625
15626    private final long[] getKsmInfo() {
15627        long[] longOut = new long[4];
15628        final int[] SINGLE_LONG_FORMAT = new int[] {
15629            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15630        };
15631        long[] longTmp = new long[1];
15632        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15633                SINGLE_LONG_FORMAT, null, longTmp, null);
15634        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15635        longTmp[0] = 0;
15636        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15637                SINGLE_LONG_FORMAT, null, longTmp, null);
15638        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15639        longTmp[0] = 0;
15640        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15641                SINGLE_LONG_FORMAT, null, longTmp, null);
15642        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15643        longTmp[0] = 0;
15644        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15645                SINGLE_LONG_FORMAT, null, longTmp, null);
15646        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15647        return longOut;
15648    }
15649
15650    private static String stringifySize(long size, int order) {
15651        Locale locale = Locale.US;
15652        switch (order) {
15653            case 1:
15654                return String.format(locale, "%,13d", size);
15655            case 1024:
15656                return String.format(locale, "%,9dK", size / 1024);
15657            case 1024 * 1024:
15658                return String.format(locale, "%,5dM", size / 1024 / 1024);
15659            case 1024 * 1024 * 1024:
15660                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15661            default:
15662                throw new IllegalArgumentException("Invalid size order");
15663        }
15664    }
15665
15666    private static String stringifyKBSize(long size) {
15667        return stringifySize(size * 1024, 1024);
15668    }
15669
15670    // Update this version number in case you change the 'compact' format
15671    private static final int MEMINFO_COMPACT_VERSION = 1;
15672
15673    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15674            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15675        boolean dumpDetails = false;
15676        boolean dumpFullDetails = false;
15677        boolean dumpDalvik = false;
15678        boolean dumpSummaryOnly = false;
15679        boolean dumpUnreachable = false;
15680        boolean oomOnly = false;
15681        boolean isCompact = false;
15682        boolean localOnly = false;
15683        boolean packages = false;
15684        boolean isCheckinRequest = false;
15685        boolean dumpSwapPss = false;
15686
15687        int opti = 0;
15688        while (opti < args.length) {
15689            String opt = args[opti];
15690            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15691                break;
15692            }
15693            opti++;
15694            if ("-a".equals(opt)) {
15695                dumpDetails = true;
15696                dumpFullDetails = true;
15697                dumpDalvik = true;
15698                dumpSwapPss = true;
15699            } else if ("-d".equals(opt)) {
15700                dumpDalvik = true;
15701            } else if ("-c".equals(opt)) {
15702                isCompact = true;
15703            } else if ("-s".equals(opt)) {
15704                dumpDetails = true;
15705                dumpSummaryOnly = true;
15706            } else if ("-S".equals(opt)) {
15707                dumpSwapPss = true;
15708            } else if ("--unreachable".equals(opt)) {
15709                dumpUnreachable = true;
15710            } else if ("--oom".equals(opt)) {
15711                oomOnly = true;
15712            } else if ("--local".equals(opt)) {
15713                localOnly = true;
15714            } else if ("--package".equals(opt)) {
15715                packages = true;
15716            } else if ("--checkin".equals(opt)) {
15717                isCheckinRequest = true;
15718
15719            } else if ("-h".equals(opt)) {
15720                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15721                pw.println("  -a: include all available information for each process.");
15722                pw.println("  -d: include dalvik details.");
15723                pw.println("  -c: dump in a compact machine-parseable representation.");
15724                pw.println("  -s: dump only summary of application memory usage.");
15725                pw.println("  -S: dump also SwapPss.");
15726                pw.println("  --oom: only show processes organized by oom adj.");
15727                pw.println("  --local: only collect details locally, don't call process.");
15728                pw.println("  --package: interpret process arg as package, dumping all");
15729                pw.println("             processes that have loaded that package.");
15730                pw.println("  --checkin: dump data for a checkin");
15731                pw.println("If [process] is specified it can be the name or ");
15732                pw.println("pid of a specific process to dump.");
15733                return;
15734            } else {
15735                pw.println("Unknown argument: " + opt + "; use -h for help");
15736            }
15737        }
15738
15739        long uptime = SystemClock.uptimeMillis();
15740        long realtime = SystemClock.elapsedRealtime();
15741        final long[] tmpLong = new long[1];
15742
15743        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15744        if (procs == null) {
15745            // No Java processes.  Maybe they want to print a native process.
15746            if (args != null && args.length > opti
15747                    && args[opti].charAt(0) != '-') {
15748                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15749                        = new ArrayList<ProcessCpuTracker.Stats>();
15750                updateCpuStatsNow();
15751                int findPid = -1;
15752                try {
15753                    findPid = Integer.parseInt(args[opti]);
15754                } catch (NumberFormatException e) {
15755                }
15756                synchronized (mProcessCpuTracker) {
15757                    final int N = mProcessCpuTracker.countStats();
15758                    for (int i=0; i<N; i++) {
15759                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15760                        if (st.pid == findPid || (st.baseName != null
15761                                && st.baseName.equals(args[opti]))) {
15762                            nativeProcs.add(st);
15763                        }
15764                    }
15765                }
15766                if (nativeProcs.size() > 0) {
15767                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15768                            isCompact);
15769                    Debug.MemoryInfo mi = null;
15770                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15771                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15772                        final int pid = r.pid;
15773                        if (!isCheckinRequest && dumpDetails) {
15774                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15775                        }
15776                        if (mi == null) {
15777                            mi = new Debug.MemoryInfo();
15778                        }
15779                        if (dumpDetails || (!brief && !oomOnly)) {
15780                            Debug.getMemoryInfo(pid, mi);
15781                        } else {
15782                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15783                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15784                        }
15785                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15786                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15787                        if (isCheckinRequest) {
15788                            pw.println();
15789                        }
15790                    }
15791                    return;
15792                }
15793            }
15794            pw.println("No process found for: " + args[opti]);
15795            return;
15796        }
15797
15798        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15799            dumpDetails = true;
15800        }
15801
15802        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15803
15804        String[] innerArgs = new String[args.length-opti];
15805        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15806
15807        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15808        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15809        long nativePss = 0;
15810        long nativeSwapPss = 0;
15811        long dalvikPss = 0;
15812        long dalvikSwapPss = 0;
15813        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15814                EmptyArray.LONG;
15815        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15816                EmptyArray.LONG;
15817        long otherPss = 0;
15818        long otherSwapPss = 0;
15819        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15820        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15821
15822        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15823        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15824        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15825                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15826
15827        long totalPss = 0;
15828        long totalSwapPss = 0;
15829        long cachedPss = 0;
15830        long cachedSwapPss = 0;
15831        boolean hasSwapPss = false;
15832
15833        Debug.MemoryInfo mi = null;
15834        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15835            final ProcessRecord r = procs.get(i);
15836            final IApplicationThread thread;
15837            final int pid;
15838            final int oomAdj;
15839            final boolean hasActivities;
15840            synchronized (this) {
15841                thread = r.thread;
15842                pid = r.pid;
15843                oomAdj = r.getSetAdjWithServices();
15844                hasActivities = r.activities.size() > 0;
15845            }
15846            if (thread != null) {
15847                if (!isCheckinRequest && dumpDetails) {
15848                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15849                }
15850                if (mi == null) {
15851                    mi = new Debug.MemoryInfo();
15852                }
15853                if (dumpDetails || (!brief && !oomOnly)) {
15854                    Debug.getMemoryInfo(pid, mi);
15855                    hasSwapPss = mi.hasSwappedOutPss;
15856                } else {
15857                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15858                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15859                }
15860                if (dumpDetails) {
15861                    if (localOnly) {
15862                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15863                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15864                        if (isCheckinRequest) {
15865                            pw.println();
15866                        }
15867                    } else {
15868                        try {
15869                            pw.flush();
15870                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15871                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15872                        } catch (RemoteException e) {
15873                            if (!isCheckinRequest) {
15874                                pw.println("Got RemoteException!");
15875                                pw.flush();
15876                            }
15877                        }
15878                    }
15879                }
15880
15881                final long myTotalPss = mi.getTotalPss();
15882                final long myTotalUss = mi.getTotalUss();
15883                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15884
15885                synchronized (this) {
15886                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15887                        // Record this for posterity if the process has been stable.
15888                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15889                    }
15890                }
15891
15892                if (!isCheckinRequest && mi != null) {
15893                    totalPss += myTotalPss;
15894                    totalSwapPss += myTotalSwapPss;
15895                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15896                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15897                            myTotalSwapPss, pid, hasActivities);
15898                    procMems.add(pssItem);
15899                    procMemsMap.put(pid, pssItem);
15900
15901                    nativePss += mi.nativePss;
15902                    nativeSwapPss += mi.nativeSwappedOutPss;
15903                    dalvikPss += mi.dalvikPss;
15904                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15905                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15906                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15907                        dalvikSubitemSwapPss[j] +=
15908                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15909                    }
15910                    otherPss += mi.otherPss;
15911                    otherSwapPss += mi.otherSwappedOutPss;
15912                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15913                        long mem = mi.getOtherPss(j);
15914                        miscPss[j] += mem;
15915                        otherPss -= mem;
15916                        mem = mi.getOtherSwappedOutPss(j);
15917                        miscSwapPss[j] += mem;
15918                        otherSwapPss -= mem;
15919                    }
15920
15921                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15922                        cachedPss += myTotalPss;
15923                        cachedSwapPss += myTotalSwapPss;
15924                    }
15925
15926                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15927                        if (oomIndex == (oomPss.length - 1)
15928                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15929                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15930                            oomPss[oomIndex] += myTotalPss;
15931                            oomSwapPss[oomIndex] += myTotalSwapPss;
15932                            if (oomProcs[oomIndex] == null) {
15933                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15934                            }
15935                            oomProcs[oomIndex].add(pssItem);
15936                            break;
15937                        }
15938                    }
15939                }
15940            }
15941        }
15942
15943        long nativeProcTotalPss = 0;
15944
15945        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15946            // If we are showing aggregations, also look for native processes to
15947            // include so that our aggregations are more accurate.
15948            updateCpuStatsNow();
15949            mi = null;
15950            synchronized (mProcessCpuTracker) {
15951                final int N = mProcessCpuTracker.countStats();
15952                for (int i=0; i<N; i++) {
15953                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15954                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15955                        if (mi == null) {
15956                            mi = new Debug.MemoryInfo();
15957                        }
15958                        if (!brief && !oomOnly) {
15959                            Debug.getMemoryInfo(st.pid, mi);
15960                        } else {
15961                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15962                            mi.nativePrivateDirty = (int)tmpLong[0];
15963                        }
15964
15965                        final long myTotalPss = mi.getTotalPss();
15966                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15967                        totalPss += myTotalPss;
15968                        nativeProcTotalPss += myTotalPss;
15969
15970                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15971                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15972                        procMems.add(pssItem);
15973
15974                        nativePss += mi.nativePss;
15975                        nativeSwapPss += mi.nativeSwappedOutPss;
15976                        dalvikPss += mi.dalvikPss;
15977                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15978                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15979                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15980                            dalvikSubitemSwapPss[j] +=
15981                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15982                        }
15983                        otherPss += mi.otherPss;
15984                        otherSwapPss += mi.otherSwappedOutPss;
15985                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15986                            long mem = mi.getOtherPss(j);
15987                            miscPss[j] += mem;
15988                            otherPss -= mem;
15989                            mem = mi.getOtherSwappedOutPss(j);
15990                            miscSwapPss[j] += mem;
15991                            otherSwapPss -= mem;
15992                        }
15993                        oomPss[0] += myTotalPss;
15994                        oomSwapPss[0] += myTotalSwapPss;
15995                        if (oomProcs[0] == null) {
15996                            oomProcs[0] = new ArrayList<MemItem>();
15997                        }
15998                        oomProcs[0].add(pssItem);
15999                    }
16000                }
16001            }
16002
16003            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16004
16005            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16006            final MemItem dalvikItem =
16007                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16008            if (dalvikSubitemPss.length > 0) {
16009                dalvikItem.subitems = new ArrayList<MemItem>();
16010                for (int j=0; j<dalvikSubitemPss.length; j++) {
16011                    final String name = Debug.MemoryInfo.getOtherLabel(
16012                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16013                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16014                                    dalvikSubitemSwapPss[j], j));
16015                }
16016            }
16017            catMems.add(dalvikItem);
16018            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16019            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16020                String label = Debug.MemoryInfo.getOtherLabel(j);
16021                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16022            }
16023
16024            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16025            for (int j=0; j<oomPss.length; j++) {
16026                if (oomPss[j] != 0) {
16027                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16028                            : DUMP_MEM_OOM_LABEL[j];
16029                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16030                            DUMP_MEM_OOM_ADJ[j]);
16031                    item.subitems = oomProcs[j];
16032                    oomMems.add(item);
16033                }
16034            }
16035
16036            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16037            if (!brief && !oomOnly && !isCompact) {
16038                pw.println();
16039                pw.println("Total PSS by process:");
16040                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16041                pw.println();
16042            }
16043            if (!isCompact) {
16044                pw.println("Total PSS by OOM adjustment:");
16045            }
16046            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16047            if (!brief && !oomOnly) {
16048                PrintWriter out = categoryPw != null ? categoryPw : pw;
16049                if (!isCompact) {
16050                    out.println();
16051                    out.println("Total PSS by category:");
16052                }
16053                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16054            }
16055            if (!isCompact) {
16056                pw.println();
16057            }
16058            MemInfoReader memInfo = new MemInfoReader();
16059            memInfo.readMemInfo();
16060            if (nativeProcTotalPss > 0) {
16061                synchronized (this) {
16062                    final long cachedKb = memInfo.getCachedSizeKb();
16063                    final long freeKb = memInfo.getFreeSizeKb();
16064                    final long zramKb = memInfo.getZramTotalSizeKb();
16065                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16066                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16067                            kernelKb*1024, nativeProcTotalPss*1024);
16068                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16069                            nativeProcTotalPss);
16070                }
16071            }
16072            if (!brief) {
16073                if (!isCompact) {
16074                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16075                    pw.print(" (status ");
16076                    switch (mLastMemoryLevel) {
16077                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16078                            pw.println("normal)");
16079                            break;
16080                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16081                            pw.println("moderate)");
16082                            break;
16083                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16084                            pw.println("low)");
16085                            break;
16086                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16087                            pw.println("critical)");
16088                            break;
16089                        default:
16090                            pw.print(mLastMemoryLevel);
16091                            pw.println(")");
16092                            break;
16093                    }
16094                    pw.print(" Free RAM: ");
16095                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16096                            + memInfo.getFreeSizeKb()));
16097                    pw.print(" (");
16098                    pw.print(stringifyKBSize(cachedPss));
16099                    pw.print(" cached pss + ");
16100                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16101                    pw.print(" cached kernel + ");
16102                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16103                    pw.println(" free)");
16104                } else {
16105                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16106                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16107                            + memInfo.getFreeSizeKb()); pw.print(",");
16108                    pw.println(totalPss - cachedPss);
16109                }
16110            }
16111            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16112                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16113                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16114            if (!isCompact) {
16115                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16116                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16117                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16118                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16119                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16120            } else {
16121                pw.print("lostram,"); pw.println(lostRAM);
16122            }
16123            if (!brief) {
16124                if (memInfo.getZramTotalSizeKb() != 0) {
16125                    if (!isCompact) {
16126                        pw.print("     ZRAM: ");
16127                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16128                                pw.print(" physical used for ");
16129                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16130                                        - memInfo.getSwapFreeSizeKb()));
16131                                pw.print(" in swap (");
16132                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16133                                pw.println(" total swap)");
16134                    } else {
16135                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16136                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16137                                pw.println(memInfo.getSwapFreeSizeKb());
16138                    }
16139                }
16140                final long[] ksm = getKsmInfo();
16141                if (!isCompact) {
16142                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16143                            || ksm[KSM_VOLATILE] != 0) {
16144                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16145                                pw.print(" saved from shared ");
16146                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16147                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16148                                pw.print(" unshared; ");
16149                                pw.print(stringifyKBSize(
16150                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16151                    }
16152                    pw.print("   Tuning: ");
16153                    pw.print(ActivityManager.staticGetMemoryClass());
16154                    pw.print(" (large ");
16155                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16156                    pw.print("), oom ");
16157                    pw.print(stringifySize(
16158                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16159                    pw.print(", restore limit ");
16160                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16161                    if (ActivityManager.isLowRamDeviceStatic()) {
16162                        pw.print(" (low-ram)");
16163                    }
16164                    if (ActivityManager.isHighEndGfx()) {
16165                        pw.print(" (high-end-gfx)");
16166                    }
16167                    pw.println();
16168                } else {
16169                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16170                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16171                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16172                    pw.print("tuning,");
16173                    pw.print(ActivityManager.staticGetMemoryClass());
16174                    pw.print(',');
16175                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16176                    pw.print(',');
16177                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16178                    if (ActivityManager.isLowRamDeviceStatic()) {
16179                        pw.print(",low-ram");
16180                    }
16181                    if (ActivityManager.isHighEndGfx()) {
16182                        pw.print(",high-end-gfx");
16183                    }
16184                    pw.println();
16185                }
16186            }
16187        }
16188    }
16189
16190    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16191            long memtrack, String name) {
16192        sb.append("  ");
16193        sb.append(ProcessList.makeOomAdjString(oomAdj));
16194        sb.append(' ');
16195        sb.append(ProcessList.makeProcStateString(procState));
16196        sb.append(' ');
16197        ProcessList.appendRamKb(sb, pss);
16198        sb.append(": ");
16199        sb.append(name);
16200        if (memtrack > 0) {
16201            sb.append(" (");
16202            sb.append(stringifyKBSize(memtrack));
16203            sb.append(" memtrack)");
16204        }
16205    }
16206
16207    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16208        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16209        sb.append(" (pid ");
16210        sb.append(mi.pid);
16211        sb.append(") ");
16212        sb.append(mi.adjType);
16213        sb.append('\n');
16214        if (mi.adjReason != null) {
16215            sb.append("                      ");
16216            sb.append(mi.adjReason);
16217            sb.append('\n');
16218        }
16219    }
16220
16221    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16222        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16223        for (int i=0, N=memInfos.size(); i<N; i++) {
16224            ProcessMemInfo mi = memInfos.get(i);
16225            infoMap.put(mi.pid, mi);
16226        }
16227        updateCpuStatsNow();
16228        long[] memtrackTmp = new long[1];
16229        synchronized (mProcessCpuTracker) {
16230            final int N = mProcessCpuTracker.countStats();
16231            for (int i=0; i<N; i++) {
16232                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16233                if (st.vsize > 0) {
16234                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16235                    if (pss > 0) {
16236                        if (infoMap.indexOfKey(st.pid) < 0) {
16237                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16238                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16239                            mi.pss = pss;
16240                            mi.memtrack = memtrackTmp[0];
16241                            memInfos.add(mi);
16242                        }
16243                    }
16244                }
16245            }
16246        }
16247
16248        long totalPss = 0;
16249        long totalMemtrack = 0;
16250        for (int i=0, N=memInfos.size(); i<N; i++) {
16251            ProcessMemInfo mi = memInfos.get(i);
16252            if (mi.pss == 0) {
16253                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16254                mi.memtrack = memtrackTmp[0];
16255            }
16256            totalPss += mi.pss;
16257            totalMemtrack += mi.memtrack;
16258        }
16259        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16260            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16261                if (lhs.oomAdj != rhs.oomAdj) {
16262                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16263                }
16264                if (lhs.pss != rhs.pss) {
16265                    return lhs.pss < rhs.pss ? 1 : -1;
16266                }
16267                return 0;
16268            }
16269        });
16270
16271        StringBuilder tag = new StringBuilder(128);
16272        StringBuilder stack = new StringBuilder(128);
16273        tag.append("Low on memory -- ");
16274        appendMemBucket(tag, totalPss, "total", false);
16275        appendMemBucket(stack, totalPss, "total", true);
16276
16277        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16278        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16279        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16280
16281        boolean firstLine = true;
16282        int lastOomAdj = Integer.MIN_VALUE;
16283        long extraNativeRam = 0;
16284        long extraNativeMemtrack = 0;
16285        long cachedPss = 0;
16286        for (int i=0, N=memInfos.size(); i<N; i++) {
16287            ProcessMemInfo mi = memInfos.get(i);
16288
16289            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16290                cachedPss += mi.pss;
16291            }
16292
16293            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16294                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16295                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16296                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16297                if (lastOomAdj != mi.oomAdj) {
16298                    lastOomAdj = mi.oomAdj;
16299                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16300                        tag.append(" / ");
16301                    }
16302                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16303                        if (firstLine) {
16304                            stack.append(":");
16305                            firstLine = false;
16306                        }
16307                        stack.append("\n\t at ");
16308                    } else {
16309                        stack.append("$");
16310                    }
16311                } else {
16312                    tag.append(" ");
16313                    stack.append("$");
16314                }
16315                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16316                    appendMemBucket(tag, mi.pss, mi.name, false);
16317                }
16318                appendMemBucket(stack, mi.pss, mi.name, true);
16319                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16320                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16321                    stack.append("(");
16322                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16323                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16324                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16325                            stack.append(":");
16326                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16327                        }
16328                    }
16329                    stack.append(")");
16330                }
16331            }
16332
16333            appendMemInfo(fullNativeBuilder, mi);
16334            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16335                // The short form only has native processes that are >= 512K.
16336                if (mi.pss >= 512) {
16337                    appendMemInfo(shortNativeBuilder, mi);
16338                } else {
16339                    extraNativeRam += mi.pss;
16340                    extraNativeMemtrack += mi.memtrack;
16341                }
16342            } else {
16343                // Short form has all other details, but if we have collected RAM
16344                // from smaller native processes let's dump a summary of that.
16345                if (extraNativeRam > 0) {
16346                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16347                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16348                    shortNativeBuilder.append('\n');
16349                    extraNativeRam = 0;
16350                }
16351                appendMemInfo(fullJavaBuilder, mi);
16352            }
16353        }
16354
16355        fullJavaBuilder.append("           ");
16356        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16357        fullJavaBuilder.append(": TOTAL");
16358        if (totalMemtrack > 0) {
16359            fullJavaBuilder.append(" (");
16360            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16361            fullJavaBuilder.append(" memtrack)");
16362        } else {
16363        }
16364        fullJavaBuilder.append("\n");
16365
16366        MemInfoReader memInfo = new MemInfoReader();
16367        memInfo.readMemInfo();
16368        final long[] infos = memInfo.getRawInfo();
16369
16370        StringBuilder memInfoBuilder = new StringBuilder(1024);
16371        Debug.getMemInfo(infos);
16372        memInfoBuilder.append("  MemInfo: ");
16373        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16374        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16375        memInfoBuilder.append(stringifyKBSize(
16376                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16377        memInfoBuilder.append(stringifyKBSize(
16378                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16379        memInfoBuilder.append(stringifyKBSize(
16380                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16381        memInfoBuilder.append("           ");
16382        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16383        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16384        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16385        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16386        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16387            memInfoBuilder.append("  ZRAM: ");
16388            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16389            memInfoBuilder.append(" RAM, ");
16390            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16391            memInfoBuilder.append(" swap total, ");
16392            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16393            memInfoBuilder.append(" swap free\n");
16394        }
16395        final long[] ksm = getKsmInfo();
16396        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16397                || ksm[KSM_VOLATILE] != 0) {
16398            memInfoBuilder.append("  KSM: ");
16399            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16400            memInfoBuilder.append(" saved from shared ");
16401            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16402            memInfoBuilder.append("\n       ");
16403            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16404            memInfoBuilder.append(" unshared; ");
16405            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16406            memInfoBuilder.append(" volatile\n");
16407        }
16408        memInfoBuilder.append("  Free RAM: ");
16409        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16410                + memInfo.getFreeSizeKb()));
16411        memInfoBuilder.append("\n");
16412        memInfoBuilder.append("  Used RAM: ");
16413        memInfoBuilder.append(stringifyKBSize(
16414                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16415        memInfoBuilder.append("\n");
16416        memInfoBuilder.append("  Lost RAM: ");
16417        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16418                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16419                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16420        memInfoBuilder.append("\n");
16421        Slog.i(TAG, "Low on memory:");
16422        Slog.i(TAG, shortNativeBuilder.toString());
16423        Slog.i(TAG, fullJavaBuilder.toString());
16424        Slog.i(TAG, memInfoBuilder.toString());
16425
16426        StringBuilder dropBuilder = new StringBuilder(1024);
16427        /*
16428        StringWriter oomSw = new StringWriter();
16429        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16430        StringWriter catSw = new StringWriter();
16431        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16432        String[] emptyArgs = new String[] { };
16433        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16434        oomPw.flush();
16435        String oomString = oomSw.toString();
16436        */
16437        dropBuilder.append("Low on memory:");
16438        dropBuilder.append(stack);
16439        dropBuilder.append('\n');
16440        dropBuilder.append(fullNativeBuilder);
16441        dropBuilder.append(fullJavaBuilder);
16442        dropBuilder.append('\n');
16443        dropBuilder.append(memInfoBuilder);
16444        dropBuilder.append('\n');
16445        /*
16446        dropBuilder.append(oomString);
16447        dropBuilder.append('\n');
16448        */
16449        StringWriter catSw = new StringWriter();
16450        synchronized (ActivityManagerService.this) {
16451            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16452            String[] emptyArgs = new String[] { };
16453            catPw.println();
16454            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16455            catPw.println();
16456            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16457                    false, null).dumpLocked();
16458            catPw.println();
16459            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16460            catPw.flush();
16461        }
16462        dropBuilder.append(catSw.toString());
16463        addErrorToDropBox("lowmem", null, "system_server", null,
16464                null, tag.toString(), dropBuilder.toString(), null, null);
16465        //Slog.i(TAG, "Sent to dropbox:");
16466        //Slog.i(TAG, dropBuilder.toString());
16467        synchronized (ActivityManagerService.this) {
16468            long now = SystemClock.uptimeMillis();
16469            if (mLastMemUsageReportTime < now) {
16470                mLastMemUsageReportTime = now;
16471            }
16472        }
16473    }
16474
16475    /**
16476     * Searches array of arguments for the specified string
16477     * @param args array of argument strings
16478     * @param value value to search for
16479     * @return true if the value is contained in the array
16480     */
16481    private static boolean scanArgs(String[] args, String value) {
16482        if (args != null) {
16483            for (String arg : args) {
16484                if (value.equals(arg)) {
16485                    return true;
16486                }
16487            }
16488        }
16489        return false;
16490    }
16491
16492    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16493            ContentProviderRecord cpr, boolean always) {
16494        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16495
16496        if (!inLaunching || always) {
16497            synchronized (cpr) {
16498                cpr.launchingApp = null;
16499                cpr.notifyAll();
16500            }
16501            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16502            String names[] = cpr.info.authority.split(";");
16503            for (int j = 0; j < names.length; j++) {
16504                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16505            }
16506        }
16507
16508        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16509            ContentProviderConnection conn = cpr.connections.get(i);
16510            if (conn.waiting) {
16511                // If this connection is waiting for the provider, then we don't
16512                // need to mess with its process unless we are always removing
16513                // or for some reason the provider is not currently launching.
16514                if (inLaunching && !always) {
16515                    continue;
16516                }
16517            }
16518            ProcessRecord capp = conn.client;
16519            conn.dead = true;
16520            if (conn.stableCount > 0) {
16521                if (!capp.persistent && capp.thread != null
16522                        && capp.pid != 0
16523                        && capp.pid != MY_PID) {
16524                    capp.kill("depends on provider "
16525                            + cpr.name.flattenToShortString()
16526                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16527                }
16528            } else if (capp.thread != null && conn.provider.provider != null) {
16529                try {
16530                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16531                } catch (RemoteException e) {
16532                }
16533                // In the protocol here, we don't expect the client to correctly
16534                // clean up this connection, we'll just remove it.
16535                cpr.connections.remove(i);
16536                if (conn.client.conProviders.remove(conn)) {
16537                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16538                }
16539            }
16540        }
16541
16542        if (inLaunching && always) {
16543            mLaunchingProviders.remove(cpr);
16544        }
16545        return inLaunching;
16546    }
16547
16548    /**
16549     * Main code for cleaning up a process when it has gone away.  This is
16550     * called both as a result of the process dying, or directly when stopping
16551     * a process when running in single process mode.
16552     *
16553     * @return Returns true if the given process has been restarted, so the
16554     * app that was passed in must remain on the process lists.
16555     */
16556    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16557            boolean restarting, boolean allowRestart, int index) {
16558        if (index >= 0) {
16559            removeLruProcessLocked(app);
16560            ProcessList.remove(app.pid);
16561        }
16562
16563        mProcessesToGc.remove(app);
16564        mPendingPssProcesses.remove(app);
16565
16566        // Dismiss any open dialogs.
16567        if (app.crashDialog != null && !app.forceCrashReport) {
16568            app.crashDialog.dismiss();
16569            app.crashDialog = null;
16570        }
16571        if (app.anrDialog != null) {
16572            app.anrDialog.dismiss();
16573            app.anrDialog = null;
16574        }
16575        if (app.waitDialog != null) {
16576            app.waitDialog.dismiss();
16577            app.waitDialog = null;
16578        }
16579
16580        app.crashing = false;
16581        app.notResponding = false;
16582
16583        app.resetPackageList(mProcessStats);
16584        app.unlinkDeathRecipient();
16585        app.makeInactive(mProcessStats);
16586        app.waitingToKill = null;
16587        app.forcingToForeground = null;
16588        updateProcessForegroundLocked(app, false, false);
16589        app.foregroundActivities = false;
16590        app.hasShownUi = false;
16591        app.treatLikeActivity = false;
16592        app.hasAboveClient = false;
16593        app.hasClientActivities = false;
16594
16595        mServices.killServicesLocked(app, allowRestart);
16596
16597        boolean restart = false;
16598
16599        // Remove published content providers.
16600        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16601            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16602            final boolean always = app.bad || !allowRestart;
16603            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16604            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16605                // We left the provider in the launching list, need to
16606                // restart it.
16607                restart = true;
16608            }
16609
16610            cpr.provider = null;
16611            cpr.proc = null;
16612        }
16613        app.pubProviders.clear();
16614
16615        // Take care of any launching providers waiting for this process.
16616        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16617            restart = true;
16618        }
16619
16620        // Unregister from connected content providers.
16621        if (!app.conProviders.isEmpty()) {
16622            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16623                ContentProviderConnection conn = app.conProviders.get(i);
16624                conn.provider.connections.remove(conn);
16625                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16626                        conn.provider.name);
16627            }
16628            app.conProviders.clear();
16629        }
16630
16631        // At this point there may be remaining entries in mLaunchingProviders
16632        // where we were the only one waiting, so they are no longer of use.
16633        // Look for these and clean up if found.
16634        // XXX Commented out for now.  Trying to figure out a way to reproduce
16635        // the actual situation to identify what is actually going on.
16636        if (false) {
16637            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16638                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16639                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16640                    synchronized (cpr) {
16641                        cpr.launchingApp = null;
16642                        cpr.notifyAll();
16643                    }
16644                }
16645            }
16646        }
16647
16648        skipCurrentReceiverLocked(app);
16649
16650        // Unregister any receivers.
16651        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16652            removeReceiverLocked(app.receivers.valueAt(i));
16653        }
16654        app.receivers.clear();
16655
16656        // If the app is undergoing backup, tell the backup manager about it
16657        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16658            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16659                    + mBackupTarget.appInfo + " died during backup");
16660            try {
16661                IBackupManager bm = IBackupManager.Stub.asInterface(
16662                        ServiceManager.getService(Context.BACKUP_SERVICE));
16663                bm.agentDisconnected(app.info.packageName);
16664            } catch (RemoteException e) {
16665                // can't happen; backup manager is local
16666            }
16667        }
16668
16669        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16670            ProcessChangeItem item = mPendingProcessChanges.get(i);
16671            if (item.pid == app.pid) {
16672                mPendingProcessChanges.remove(i);
16673                mAvailProcessChanges.add(item);
16674            }
16675        }
16676        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16677                null).sendToTarget();
16678
16679        // If the caller is restarting this app, then leave it in its
16680        // current lists and let the caller take care of it.
16681        if (restarting) {
16682            return false;
16683        }
16684
16685        if (!app.persistent || app.isolated) {
16686            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16687                    "Removing non-persistent process during cleanup: " + app);
16688            removeProcessNameLocked(app.processName, app.uid);
16689            if (mHeavyWeightProcess == app) {
16690                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16691                        mHeavyWeightProcess.userId, 0));
16692                mHeavyWeightProcess = null;
16693            }
16694        } else if (!app.removed) {
16695            // This app is persistent, so we need to keep its record around.
16696            // If it is not already on the pending app list, add it there
16697            // and start a new process for it.
16698            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16699                mPersistentStartingProcesses.add(app);
16700                restart = true;
16701            }
16702        }
16703        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16704                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16705        mProcessesOnHold.remove(app);
16706
16707        if (app == mHomeProcess) {
16708            mHomeProcess = null;
16709        }
16710        if (app == mPreviousProcess) {
16711            mPreviousProcess = null;
16712        }
16713
16714        if (restart && !app.isolated) {
16715            // We have components that still need to be running in the
16716            // process, so re-launch it.
16717            if (index < 0) {
16718                ProcessList.remove(app.pid);
16719            }
16720            addProcessNameLocked(app);
16721            startProcessLocked(app, "restart", app.processName);
16722            return true;
16723        } else if (app.pid > 0 && app.pid != MY_PID) {
16724            // Goodbye!
16725            boolean removed;
16726            synchronized (mPidsSelfLocked) {
16727                mPidsSelfLocked.remove(app.pid);
16728                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16729            }
16730            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16731            if (app.isolated) {
16732                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16733            }
16734            app.setPid(0);
16735        }
16736        return false;
16737    }
16738
16739    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16740        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16741            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16742            if (cpr.launchingApp == app) {
16743                return true;
16744            }
16745        }
16746        return false;
16747    }
16748
16749    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16750        // Look through the content providers we are waiting to have launched,
16751        // and if any run in this process then either schedule a restart of
16752        // the process or kill the client waiting for it if this process has
16753        // gone bad.
16754        boolean restart = false;
16755        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16756            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16757            if (cpr.launchingApp == app) {
16758                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16759                    restart = true;
16760                } else {
16761                    removeDyingProviderLocked(app, cpr, true);
16762                }
16763            }
16764        }
16765        return restart;
16766    }
16767
16768    // =========================================================
16769    // SERVICES
16770    // =========================================================
16771
16772    @Override
16773    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16774            int flags) {
16775        enforceNotIsolatedCaller("getServices");
16776        synchronized (this) {
16777            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16778        }
16779    }
16780
16781    @Override
16782    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16783        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16784        synchronized (this) {
16785            return mServices.getRunningServiceControlPanelLocked(name);
16786        }
16787    }
16788
16789    @Override
16790    public ComponentName startService(IApplicationThread caller, Intent service,
16791            String resolvedType, String callingPackage, int userId)
16792            throws TransactionTooLargeException {
16793        enforceNotIsolatedCaller("startService");
16794        // Refuse possible leaked file descriptors
16795        if (service != null && service.hasFileDescriptors() == true) {
16796            throw new IllegalArgumentException("File descriptors passed in Intent");
16797        }
16798
16799        if (callingPackage == null) {
16800            throw new IllegalArgumentException("callingPackage cannot be null");
16801        }
16802
16803        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16804                "startService: " + service + " type=" + resolvedType);
16805        synchronized(this) {
16806            final int callingPid = Binder.getCallingPid();
16807            final int callingUid = Binder.getCallingUid();
16808            final long origId = Binder.clearCallingIdentity();
16809            ComponentName res = mServices.startServiceLocked(caller, service,
16810                    resolvedType, callingPid, callingUid, callingPackage, userId);
16811            Binder.restoreCallingIdentity(origId);
16812            return res;
16813        }
16814    }
16815
16816    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16817            String callingPackage, int userId)
16818            throws TransactionTooLargeException {
16819        synchronized(this) {
16820            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16821                    "startServiceInPackage: " + service + " type=" + resolvedType);
16822            final long origId = Binder.clearCallingIdentity();
16823            ComponentName res = mServices.startServiceLocked(null, service,
16824                    resolvedType, -1, uid, callingPackage, userId);
16825            Binder.restoreCallingIdentity(origId);
16826            return res;
16827        }
16828    }
16829
16830    @Override
16831    public int stopService(IApplicationThread caller, Intent service,
16832            String resolvedType, int userId) {
16833        enforceNotIsolatedCaller("stopService");
16834        // Refuse possible leaked file descriptors
16835        if (service != null && service.hasFileDescriptors() == true) {
16836            throw new IllegalArgumentException("File descriptors passed in Intent");
16837        }
16838
16839        synchronized(this) {
16840            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16841        }
16842    }
16843
16844    @Override
16845    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16846        enforceNotIsolatedCaller("peekService");
16847        // Refuse possible leaked file descriptors
16848        if (service != null && service.hasFileDescriptors() == true) {
16849            throw new IllegalArgumentException("File descriptors passed in Intent");
16850        }
16851
16852        if (callingPackage == null) {
16853            throw new IllegalArgumentException("callingPackage cannot be null");
16854        }
16855
16856        synchronized(this) {
16857            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16858        }
16859    }
16860
16861    @Override
16862    public boolean stopServiceToken(ComponentName className, IBinder token,
16863            int startId) {
16864        synchronized(this) {
16865            return mServices.stopServiceTokenLocked(className, token, startId);
16866        }
16867    }
16868
16869    @Override
16870    public void setServiceForeground(ComponentName className, IBinder token,
16871            int id, Notification notification, int flags) {
16872        synchronized(this) {
16873            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16874        }
16875    }
16876
16877    @Override
16878    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16879            boolean requireFull, String name, String callerPackage) {
16880        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16881                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16882    }
16883
16884    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16885            String className, int flags) {
16886        boolean result = false;
16887        // For apps that don't have pre-defined UIDs, check for permission
16888        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16889            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16890                if (ActivityManager.checkUidPermission(
16891                        INTERACT_ACROSS_USERS,
16892                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16893                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16894                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16895                            + " requests FLAG_SINGLE_USER, but app does not hold "
16896                            + INTERACT_ACROSS_USERS;
16897                    Slog.w(TAG, msg);
16898                    throw new SecurityException(msg);
16899                }
16900                // Permission passed
16901                result = true;
16902            }
16903        } else if ("system".equals(componentProcessName)) {
16904            result = true;
16905        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16906            // Phone app and persistent apps are allowed to export singleuser providers.
16907            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16908                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16909        }
16910        if (DEBUG_MU) Slog.v(TAG_MU,
16911                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16912                + Integer.toHexString(flags) + ") = " + result);
16913        return result;
16914    }
16915
16916    /**
16917     * Checks to see if the caller is in the same app as the singleton
16918     * component, or the component is in a special app. It allows special apps
16919     * to export singleton components but prevents exporting singleton
16920     * components for regular apps.
16921     */
16922    boolean isValidSingletonCall(int callingUid, int componentUid) {
16923        int componentAppId = UserHandle.getAppId(componentUid);
16924        return UserHandle.isSameApp(callingUid, componentUid)
16925                || componentAppId == Process.SYSTEM_UID
16926                || componentAppId == Process.PHONE_UID
16927                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16928                        == PackageManager.PERMISSION_GRANTED;
16929    }
16930
16931    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16932            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16933            int userId) throws TransactionTooLargeException {
16934        enforceNotIsolatedCaller("bindService");
16935
16936        // Refuse possible leaked file descriptors
16937        if (service != null && service.hasFileDescriptors() == true) {
16938            throw new IllegalArgumentException("File descriptors passed in Intent");
16939        }
16940
16941        if (callingPackage == null) {
16942            throw new IllegalArgumentException("callingPackage cannot be null");
16943        }
16944
16945        synchronized(this) {
16946            return mServices.bindServiceLocked(caller, token, service,
16947                    resolvedType, connection, flags, callingPackage, userId);
16948        }
16949    }
16950
16951    public boolean unbindService(IServiceConnection connection) {
16952        synchronized (this) {
16953            return mServices.unbindServiceLocked(connection);
16954        }
16955    }
16956
16957    public void publishService(IBinder token, Intent intent, IBinder service) {
16958        // Refuse possible leaked file descriptors
16959        if (intent != null && intent.hasFileDescriptors() == true) {
16960            throw new IllegalArgumentException("File descriptors passed in Intent");
16961        }
16962
16963        synchronized(this) {
16964            if (!(token instanceof ServiceRecord)) {
16965                throw new IllegalArgumentException("Invalid service token");
16966            }
16967            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16968        }
16969    }
16970
16971    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16972        // Refuse possible leaked file descriptors
16973        if (intent != null && intent.hasFileDescriptors() == true) {
16974            throw new IllegalArgumentException("File descriptors passed in Intent");
16975        }
16976
16977        synchronized(this) {
16978            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16979        }
16980    }
16981
16982    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16983        synchronized(this) {
16984            if (!(token instanceof ServiceRecord)) {
16985                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16986                throw new IllegalArgumentException("Invalid service token");
16987            }
16988            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16989        }
16990    }
16991
16992    // =========================================================
16993    // BACKUP AND RESTORE
16994    // =========================================================
16995
16996    // Cause the target app to be launched if necessary and its backup agent
16997    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16998    // activity manager to announce its creation.
16999    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17000        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17001                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17002        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17003
17004        synchronized(this) {
17005            // !!! TODO: currently no check here that we're already bound
17006            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17007            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17008            synchronized (stats) {
17009                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17010            }
17011
17012            // Backup agent is now in use, its package can't be stopped.
17013            try {
17014                AppGlobals.getPackageManager().setPackageStoppedState(
17015                        app.packageName, false, UserHandle.getUserId(app.uid));
17016            } catch (RemoteException e) {
17017            } catch (IllegalArgumentException e) {
17018                Slog.w(TAG, "Failed trying to unstop package "
17019                        + app.packageName + ": " + e);
17020            }
17021
17022            BackupRecord r = new BackupRecord(ss, app, backupMode);
17023            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17024                    ? new ComponentName(app.packageName, app.backupAgentName)
17025                    : new ComponentName("android", "FullBackupAgent");
17026            // startProcessLocked() returns existing proc's record if it's already running
17027            ProcessRecord proc = startProcessLocked(app.processName, app,
17028                    false, 0, "backup", hostingName, false, false, false);
17029            if (proc == null) {
17030                Slog.e(TAG, "Unable to start backup agent process " + r);
17031                return false;
17032            }
17033
17034            // If the app is a regular app (uid >= 10000) and not the system server or phone
17035            // process, etc, then mark it as being in full backup so that certain calls to the
17036            // process can be blocked. This is not reset to false anywhere because we kill the
17037            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17038            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17039                proc.inFullBackup = true;
17040            }
17041            r.app = proc;
17042            mBackupTarget = r;
17043            mBackupAppName = app.packageName;
17044
17045            // Try not to kill the process during backup
17046            updateOomAdjLocked(proc);
17047
17048            // If the process is already attached, schedule the creation of the backup agent now.
17049            // If it is not yet live, this will be done when it attaches to the framework.
17050            if (proc.thread != null) {
17051                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17052                try {
17053                    proc.thread.scheduleCreateBackupAgent(app,
17054                            compatibilityInfoForPackageLocked(app), backupMode);
17055                } catch (RemoteException e) {
17056                    // Will time out on the backup manager side
17057                }
17058            } else {
17059                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17060            }
17061            // Invariants: at this point, the target app process exists and the application
17062            // is either already running or in the process of coming up.  mBackupTarget and
17063            // mBackupAppName describe the app, so that when it binds back to the AM we
17064            // know that it's scheduled for a backup-agent operation.
17065        }
17066
17067        return true;
17068    }
17069
17070    @Override
17071    public void clearPendingBackup() {
17072        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17073        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17074
17075        synchronized (this) {
17076            mBackupTarget = null;
17077            mBackupAppName = null;
17078        }
17079    }
17080
17081    // A backup agent has just come up
17082    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17083        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17084                + " = " + agent);
17085
17086        synchronized(this) {
17087            if (!agentPackageName.equals(mBackupAppName)) {
17088                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17089                return;
17090            }
17091        }
17092
17093        long oldIdent = Binder.clearCallingIdentity();
17094        try {
17095            IBackupManager bm = IBackupManager.Stub.asInterface(
17096                    ServiceManager.getService(Context.BACKUP_SERVICE));
17097            bm.agentConnected(agentPackageName, agent);
17098        } catch (RemoteException e) {
17099            // can't happen; the backup manager service is local
17100        } catch (Exception e) {
17101            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17102            e.printStackTrace();
17103        } finally {
17104            Binder.restoreCallingIdentity(oldIdent);
17105        }
17106    }
17107
17108    // done with this agent
17109    public void unbindBackupAgent(ApplicationInfo appInfo) {
17110        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17111        if (appInfo == null) {
17112            Slog.w(TAG, "unbind backup agent for null app");
17113            return;
17114        }
17115
17116        synchronized(this) {
17117            try {
17118                if (mBackupAppName == null) {
17119                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17120                    return;
17121                }
17122
17123                if (!mBackupAppName.equals(appInfo.packageName)) {
17124                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17125                    return;
17126                }
17127
17128                // Not backing this app up any more; reset its OOM adjustment
17129                final ProcessRecord proc = mBackupTarget.app;
17130                updateOomAdjLocked(proc);
17131
17132                // If the app crashed during backup, 'thread' will be null here
17133                if (proc.thread != null) {
17134                    try {
17135                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17136                                compatibilityInfoForPackageLocked(appInfo));
17137                    } catch (Exception e) {
17138                        Slog.e(TAG, "Exception when unbinding backup agent:");
17139                        e.printStackTrace();
17140                    }
17141                }
17142            } finally {
17143                mBackupTarget = null;
17144                mBackupAppName = null;
17145            }
17146        }
17147    }
17148    // =========================================================
17149    // BROADCASTS
17150    // =========================================================
17151
17152    boolean isPendingBroadcastProcessLocked(int pid) {
17153        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17154                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17155    }
17156
17157    void skipPendingBroadcastLocked(int pid) {
17158            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17159            for (BroadcastQueue queue : mBroadcastQueues) {
17160                queue.skipPendingBroadcastLocked(pid);
17161            }
17162    }
17163
17164    // The app just attached; send any pending broadcasts that it should receive
17165    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17166        boolean didSomething = false;
17167        for (BroadcastQueue queue : mBroadcastQueues) {
17168            didSomething |= queue.sendPendingBroadcastsLocked(app);
17169        }
17170        return didSomething;
17171    }
17172
17173    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17174            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17175        enforceNotIsolatedCaller("registerReceiver");
17176        ArrayList<Intent> stickyIntents = null;
17177        ProcessRecord callerApp = null;
17178        int callingUid;
17179        int callingPid;
17180        synchronized(this) {
17181            if (caller != null) {
17182                callerApp = getRecordForAppLocked(caller);
17183                if (callerApp == null) {
17184                    throw new SecurityException(
17185                            "Unable to find app for caller " + caller
17186                            + " (pid=" + Binder.getCallingPid()
17187                            + ") when registering receiver " + receiver);
17188                }
17189                if (callerApp.info.uid != Process.SYSTEM_UID &&
17190                        !callerApp.pkgList.containsKey(callerPackage) &&
17191                        !"android".equals(callerPackage)) {
17192                    throw new SecurityException("Given caller package " + callerPackage
17193                            + " is not running in process " + callerApp);
17194                }
17195                callingUid = callerApp.info.uid;
17196                callingPid = callerApp.pid;
17197            } else {
17198                callerPackage = null;
17199                callingUid = Binder.getCallingUid();
17200                callingPid = Binder.getCallingPid();
17201            }
17202
17203            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17204                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17205
17206            Iterator<String> actions = filter.actionsIterator();
17207            if (actions == null) {
17208                ArrayList<String> noAction = new ArrayList<String>(1);
17209                noAction.add(null);
17210                actions = noAction.iterator();
17211            }
17212
17213            // Collect stickies of users
17214            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17215            while (actions.hasNext()) {
17216                String action = actions.next();
17217                for (int id : userIds) {
17218                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17219                    if (stickies != null) {
17220                        ArrayList<Intent> intents = stickies.get(action);
17221                        if (intents != null) {
17222                            if (stickyIntents == null) {
17223                                stickyIntents = new ArrayList<Intent>();
17224                            }
17225                            stickyIntents.addAll(intents);
17226                        }
17227                    }
17228                }
17229            }
17230        }
17231
17232        ArrayList<Intent> allSticky = null;
17233        if (stickyIntents != null) {
17234            final ContentResolver resolver = mContext.getContentResolver();
17235            // Look for any matching sticky broadcasts...
17236            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17237                Intent intent = stickyIntents.get(i);
17238                // If intent has scheme "content", it will need to acccess
17239                // provider that needs to lock mProviderMap in ActivityThread
17240                // and also it may need to wait application response, so we
17241                // cannot lock ActivityManagerService here.
17242                if (filter.match(resolver, intent, true, TAG) >= 0) {
17243                    if (allSticky == null) {
17244                        allSticky = new ArrayList<Intent>();
17245                    }
17246                    allSticky.add(intent);
17247                }
17248            }
17249        }
17250
17251        // The first sticky in the list is returned directly back to the client.
17252        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17253        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17254        if (receiver == null) {
17255            return sticky;
17256        }
17257
17258        synchronized (this) {
17259            if (callerApp != null && (callerApp.thread == null
17260                    || callerApp.thread.asBinder() != caller.asBinder())) {
17261                // Original caller already died
17262                return null;
17263            }
17264            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17265            if (rl == null) {
17266                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17267                        userId, receiver);
17268                if (rl.app != null) {
17269                    rl.app.receivers.add(rl);
17270                } else {
17271                    try {
17272                        receiver.asBinder().linkToDeath(rl, 0);
17273                    } catch (RemoteException e) {
17274                        return sticky;
17275                    }
17276                    rl.linkedToDeath = true;
17277                }
17278                mRegisteredReceivers.put(receiver.asBinder(), rl);
17279            } else if (rl.uid != callingUid) {
17280                throw new IllegalArgumentException(
17281                        "Receiver requested to register for uid " + callingUid
17282                        + " was previously registered for uid " + rl.uid);
17283            } else if (rl.pid != callingPid) {
17284                throw new IllegalArgumentException(
17285                        "Receiver requested to register for pid " + callingPid
17286                        + " was previously registered for pid " + rl.pid);
17287            } else if (rl.userId != userId) {
17288                throw new IllegalArgumentException(
17289                        "Receiver requested to register for user " + userId
17290                        + " was previously registered for user " + rl.userId);
17291            }
17292            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17293                    permission, callingUid, userId);
17294            rl.add(bf);
17295            if (!bf.debugCheck()) {
17296                Slog.w(TAG, "==> For Dynamic broadcast");
17297            }
17298            mReceiverResolver.addFilter(bf);
17299
17300            // Enqueue broadcasts for all existing stickies that match
17301            // this filter.
17302            if (allSticky != null) {
17303                ArrayList receivers = new ArrayList();
17304                receivers.add(bf);
17305
17306                final int stickyCount = allSticky.size();
17307                for (int i = 0; i < stickyCount; i++) {
17308                    Intent intent = allSticky.get(i);
17309                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17310                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17311                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17312                            null, 0, null, null, false, true, true, -1);
17313                    queue.enqueueParallelBroadcastLocked(r);
17314                    queue.scheduleBroadcastsLocked();
17315                }
17316            }
17317
17318            return sticky;
17319        }
17320    }
17321
17322    public void unregisterReceiver(IIntentReceiver receiver) {
17323        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17324
17325        final long origId = Binder.clearCallingIdentity();
17326        try {
17327            boolean doTrim = false;
17328
17329            synchronized(this) {
17330                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17331                if (rl != null) {
17332                    final BroadcastRecord r = rl.curBroadcast;
17333                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17334                        final boolean doNext = r.queue.finishReceiverLocked(
17335                                r, r.resultCode, r.resultData, r.resultExtras,
17336                                r.resultAbort, false);
17337                        if (doNext) {
17338                            doTrim = true;
17339                            r.queue.processNextBroadcast(false);
17340                        }
17341                    }
17342
17343                    if (rl.app != null) {
17344                        rl.app.receivers.remove(rl);
17345                    }
17346                    removeReceiverLocked(rl);
17347                    if (rl.linkedToDeath) {
17348                        rl.linkedToDeath = false;
17349                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17350                    }
17351                }
17352            }
17353
17354            // If we actually concluded any broadcasts, we might now be able
17355            // to trim the recipients' apps from our working set
17356            if (doTrim) {
17357                trimApplications();
17358                return;
17359            }
17360
17361        } finally {
17362            Binder.restoreCallingIdentity(origId);
17363        }
17364    }
17365
17366    void removeReceiverLocked(ReceiverList rl) {
17367        mRegisteredReceivers.remove(rl.receiver.asBinder());
17368        for (int i = rl.size() - 1; i >= 0; i--) {
17369            mReceiverResolver.removeFilter(rl.get(i));
17370        }
17371    }
17372
17373    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17374        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17375            ProcessRecord r = mLruProcesses.get(i);
17376            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17377                try {
17378                    r.thread.dispatchPackageBroadcast(cmd, packages);
17379                } catch (RemoteException ex) {
17380                }
17381            }
17382        }
17383    }
17384
17385    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17386            int callingUid, int[] users) {
17387        // TODO: come back and remove this assumption to triage all broadcasts
17388        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17389
17390        List<ResolveInfo> receivers = null;
17391        try {
17392            HashSet<ComponentName> singleUserReceivers = null;
17393            boolean scannedFirstReceivers = false;
17394            for (int user : users) {
17395                // Skip users that have Shell restrictions, with exception of always permitted
17396                // Shell broadcasts
17397                if (callingUid == Process.SHELL_UID
17398                        && mUserController.hasUserRestriction(
17399                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17400                        && !isPermittedShellBroadcast(intent)) {
17401                    continue;
17402                }
17403                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17404                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17405                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17406                    // If this is not the system user, we need to check for
17407                    // any receivers that should be filtered out.
17408                    for (int i=0; i<newReceivers.size(); i++) {
17409                        ResolveInfo ri = newReceivers.get(i);
17410                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17411                            newReceivers.remove(i);
17412                            i--;
17413                        }
17414                    }
17415                }
17416                if (newReceivers != null && newReceivers.size() == 0) {
17417                    newReceivers = null;
17418                }
17419                if (receivers == null) {
17420                    receivers = newReceivers;
17421                } else if (newReceivers != null) {
17422                    // We need to concatenate the additional receivers
17423                    // found with what we have do far.  This would be easy,
17424                    // but we also need to de-dup any receivers that are
17425                    // singleUser.
17426                    if (!scannedFirstReceivers) {
17427                        // Collect any single user receivers we had already retrieved.
17428                        scannedFirstReceivers = true;
17429                        for (int i=0; i<receivers.size(); i++) {
17430                            ResolveInfo ri = receivers.get(i);
17431                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17432                                ComponentName cn = new ComponentName(
17433                                        ri.activityInfo.packageName, ri.activityInfo.name);
17434                                if (singleUserReceivers == null) {
17435                                    singleUserReceivers = new HashSet<ComponentName>();
17436                                }
17437                                singleUserReceivers.add(cn);
17438                            }
17439                        }
17440                    }
17441                    // Add the new results to the existing results, tracking
17442                    // and de-dupping single user receivers.
17443                    for (int i=0; i<newReceivers.size(); i++) {
17444                        ResolveInfo ri = newReceivers.get(i);
17445                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17446                            ComponentName cn = new ComponentName(
17447                                    ri.activityInfo.packageName, ri.activityInfo.name);
17448                            if (singleUserReceivers == null) {
17449                                singleUserReceivers = new HashSet<ComponentName>();
17450                            }
17451                            if (!singleUserReceivers.contains(cn)) {
17452                                singleUserReceivers.add(cn);
17453                                receivers.add(ri);
17454                            }
17455                        } else {
17456                            receivers.add(ri);
17457                        }
17458                    }
17459                }
17460            }
17461        } catch (RemoteException ex) {
17462            // pm is in same process, this will never happen.
17463        }
17464        return receivers;
17465    }
17466
17467    private boolean isPermittedShellBroadcast(Intent intent) {
17468        // remote bugreport should always be allowed to be taken
17469        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17470    }
17471
17472    final int broadcastIntentLocked(ProcessRecord callerApp,
17473            String callerPackage, Intent intent, String resolvedType,
17474            IIntentReceiver resultTo, int resultCode, String resultData,
17475            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17476            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17477        intent = new Intent(intent);
17478
17479        // By default broadcasts do not go to stopped apps.
17480        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17481
17482        // If we have not finished booting, don't allow this to launch new processes.
17483        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17484            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17485        }
17486
17487        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17488                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17489                + " ordered=" + ordered + " userid=" + userId);
17490        if ((resultTo != null) && !ordered) {
17491            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17492        }
17493
17494        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17495                ALLOW_NON_FULL, "broadcast", callerPackage);
17496
17497        // Make sure that the user who is receiving this broadcast is running.
17498        // If not, we will just skip it. Make an exception for shutdown broadcasts
17499        // and upgrade steps.
17500
17501        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17502            if ((callingUid != Process.SYSTEM_UID
17503                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17504                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17505                Slog.w(TAG, "Skipping broadcast of " + intent
17506                        + ": user " + userId + " is stopped");
17507                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17508            }
17509        }
17510
17511        BroadcastOptions brOptions = null;
17512        if (bOptions != null) {
17513            brOptions = new BroadcastOptions(bOptions);
17514            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17515                // See if the caller is allowed to do this.  Note we are checking against
17516                // the actual real caller (not whoever provided the operation as say a
17517                // PendingIntent), because that who is actually supplied the arguments.
17518                if (checkComponentPermission(
17519                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17520                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17521                        != PackageManager.PERMISSION_GRANTED) {
17522                    String msg = "Permission Denial: " + intent.getAction()
17523                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17524                            + ", uid=" + callingUid + ")"
17525                            + " requires "
17526                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17527                    Slog.w(TAG, msg);
17528                    throw new SecurityException(msg);
17529                }
17530            }
17531        }
17532
17533        // Verify that protected broadcasts are only being sent by system code,
17534        // and that system code is only sending protected broadcasts.
17535        final String action = intent.getAction();
17536        final boolean isProtectedBroadcast;
17537        try {
17538            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17539        } catch (RemoteException e) {
17540            Slog.w(TAG, "Remote exception", e);
17541            return ActivityManager.BROADCAST_SUCCESS;
17542        }
17543
17544        final boolean isCallerSystem;
17545        switch (UserHandle.getAppId(callingUid)) {
17546            case Process.ROOT_UID:
17547            case Process.SYSTEM_UID:
17548            case Process.PHONE_UID:
17549            case Process.BLUETOOTH_UID:
17550            case Process.NFC_UID:
17551                isCallerSystem = true;
17552                break;
17553            default:
17554                isCallerSystem = (callerApp != null) && callerApp.persistent;
17555                break;
17556        }
17557
17558        if (isCallerSystem) {
17559            if (isProtectedBroadcast
17560                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17561                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17562                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17563                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17564                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17565                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17566                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17567                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17568                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17569                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17570                // Broadcast is either protected, or it's a public action that
17571                // we've relaxed, so it's fine for system internals to send.
17572            } else {
17573                // The vast majority of broadcasts sent from system internals
17574                // should be protected to avoid security holes, so yell loudly
17575                // to ensure we examine these cases.
17576                if (callerApp != null) {
17577                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17578                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17579                            new Throwable());
17580                } else {
17581                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17582                            + " from system uid " + UserHandle.formatUid(callingUid)
17583                            + " pkg " + callerPackage,
17584                            new Throwable());
17585                }
17586            }
17587
17588        } else {
17589            if (isProtectedBroadcast) {
17590                String msg = "Permission Denial: not allowed to send broadcast "
17591                        + action + " from pid="
17592                        + callingPid + ", uid=" + callingUid;
17593                Slog.w(TAG, msg);
17594                throw new SecurityException(msg);
17595
17596            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17597                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17598                // Special case for compatibility: we don't want apps to send this,
17599                // but historically it has not been protected and apps may be using it
17600                // to poke their own app widget.  So, instead of making it protected,
17601                // just limit it to the caller.
17602                if (callerPackage == null) {
17603                    String msg = "Permission Denial: not allowed to send broadcast "
17604                            + action + " from unknown caller.";
17605                    Slog.w(TAG, msg);
17606                    throw new SecurityException(msg);
17607                } else if (intent.getComponent() != null) {
17608                    // They are good enough to send to an explicit component...  verify
17609                    // it is being sent to the calling app.
17610                    if (!intent.getComponent().getPackageName().equals(
17611                            callerPackage)) {
17612                        String msg = "Permission Denial: not allowed to send broadcast "
17613                                + action + " to "
17614                                + intent.getComponent().getPackageName() + " from "
17615                                + callerPackage;
17616                        Slog.w(TAG, msg);
17617                        throw new SecurityException(msg);
17618                    }
17619                } else {
17620                    // Limit broadcast to their own package.
17621                    intent.setPackage(callerPackage);
17622                }
17623            }
17624        }
17625
17626        if (action != null) {
17627            switch (action) {
17628                case Intent.ACTION_UID_REMOVED:
17629                case Intent.ACTION_PACKAGE_REMOVED:
17630                case Intent.ACTION_PACKAGE_CHANGED:
17631                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17632                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17633                case Intent.ACTION_PACKAGES_SUSPENDED:
17634                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17635                    // Handle special intents: if this broadcast is from the package
17636                    // manager about a package being removed, we need to remove all of
17637                    // its activities from the history stack.
17638                    if (checkComponentPermission(
17639                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17640                            callingPid, callingUid, -1, true)
17641                            != PackageManager.PERMISSION_GRANTED) {
17642                        String msg = "Permission Denial: " + intent.getAction()
17643                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17644                                + ", uid=" + callingUid + ")"
17645                                + " requires "
17646                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17647                        Slog.w(TAG, msg);
17648                        throw new SecurityException(msg);
17649                    }
17650                    switch (action) {
17651                        case Intent.ACTION_UID_REMOVED:
17652                            final Bundle intentExtras = intent.getExtras();
17653                            final int uid = intentExtras != null
17654                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17655                            if (uid >= 0) {
17656                                mBatteryStatsService.removeUid(uid);
17657                                mAppOpsService.uidRemoved(uid);
17658                            }
17659                            break;
17660                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17661                            // If resources are unavailable just force stop all those packages
17662                            // and flush the attribute cache as well.
17663                            String list[] =
17664                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17665                            if (list != null && list.length > 0) {
17666                                for (int i = 0; i < list.length; i++) {
17667                                    forceStopPackageLocked(list[i], -1, false, true, true,
17668                                            false, false, userId, "storage unmount");
17669                                }
17670                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17671                                sendPackageBroadcastLocked(
17672                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17673                                        userId);
17674                            }
17675                            break;
17676                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17677                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17678                            break;
17679                        case Intent.ACTION_PACKAGE_REMOVED:
17680                        case Intent.ACTION_PACKAGE_CHANGED:
17681                            Uri data = intent.getData();
17682                            String ssp;
17683                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17684                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17685                                final boolean replacing =
17686                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17687                                final boolean killProcess =
17688                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17689                                final boolean fullUninstall = removed && !replacing;
17690                                if (removed) {
17691                                    if (killProcess) {
17692                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17693                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17694                                                false, true, true, false, fullUninstall, userId,
17695                                                removed ? "pkg removed" : "pkg changed");
17696                                    }
17697                                    final int cmd = killProcess
17698                                            ? IApplicationThread.PACKAGE_REMOVED
17699                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17700                                    sendPackageBroadcastLocked(cmd,
17701                                            new String[] {ssp}, userId);
17702                                    if (fullUninstall) {
17703                                        mAppOpsService.packageRemoved(
17704                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17705
17706                                        // Remove all permissions granted from/to this package
17707                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17708
17709                                        removeTasksByPackageNameLocked(ssp, userId);
17710                                        mBatteryStatsService.notePackageUninstalled(ssp);
17711                                    }
17712                                } else {
17713                                    if (killProcess) {
17714                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17715                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17716                                                userId, ProcessList.INVALID_ADJ,
17717                                                false, true, true, false, "change " + ssp);
17718                                    }
17719                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17720                                            intent.getStringArrayExtra(
17721                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17722                                }
17723                            }
17724                            break;
17725                        case Intent.ACTION_PACKAGES_SUSPENDED:
17726                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17727                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17728                                    intent.getAction());
17729                            final String[] packageNames = intent.getStringArrayExtra(
17730                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17731                            final int userHandle = intent.getIntExtra(
17732                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17733
17734                            synchronized(ActivityManagerService.this) {
17735                                mRecentTasks.onPackagesSuspendedChanged(
17736                                        packageNames, suspended, userHandle);
17737                            }
17738                            break;
17739                    }
17740                    break;
17741                case Intent.ACTION_PACKAGE_REPLACED:
17742                {
17743                    final Uri data = intent.getData();
17744                    final String ssp;
17745                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17746                        final ApplicationInfo aInfo =
17747                                getPackageManagerInternalLocked().getApplicationInfo(
17748                                        ssp,
17749                                        userId);
17750                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17751                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17752                                new String[] {ssp}, userId);
17753                    }
17754                    break;
17755                }
17756                case Intent.ACTION_PACKAGE_ADDED:
17757                {
17758                    // Special case for adding a package: by default turn on compatibility mode.
17759                    Uri data = intent.getData();
17760                    String ssp;
17761                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17762                        final boolean replacing =
17763                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17764                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17765
17766                        try {
17767                            ApplicationInfo ai = AppGlobals.getPackageManager().
17768                                    getApplicationInfo(ssp, 0, 0);
17769                            mBatteryStatsService.notePackageInstalled(ssp,
17770                                    ai != null ? ai.versionCode : 0);
17771                        } catch (RemoteException e) {
17772                        }
17773                    }
17774                    break;
17775                }
17776                case Intent.ACTION_TIMEZONE_CHANGED:
17777                    // If this is the time zone changed action, queue up a message that will reset
17778                    // the timezone of all currently running processes. This message will get
17779                    // queued up before the broadcast happens.
17780                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17781                    break;
17782                case Intent.ACTION_TIME_CHANGED:
17783                    // If the user set the time, let all running processes know.
17784                    final int is24Hour =
17785                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17786                                    : 0;
17787                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17788                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17789                    synchronized (stats) {
17790                        stats.noteCurrentTimeChangedLocked();
17791                    }
17792                    break;
17793                case Intent.ACTION_CLEAR_DNS_CACHE:
17794                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17795                    break;
17796                case Proxy.PROXY_CHANGE_ACTION:
17797                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17798                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17799                    break;
17800                case android.hardware.Camera.ACTION_NEW_PICTURE:
17801                case android.hardware.Camera.ACTION_NEW_VIDEO:
17802                    // These broadcasts are no longer allowed by the system, since they can
17803                    // cause significant thrashing at a crictical point (using the camera).
17804                    // Apps should use JobScehduler to monitor for media provider changes.
17805                    Slog.w(TAG, action + " no longer allowed; dropping from "
17806                            + UserHandle.formatUid(callingUid));
17807                    // Lie; we don't want to crash the app.
17808                    return ActivityManager.BROADCAST_SUCCESS;
17809            }
17810        }
17811
17812        // Add to the sticky list if requested.
17813        if (sticky) {
17814            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17815                    callingPid, callingUid)
17816                    != PackageManager.PERMISSION_GRANTED) {
17817                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17818                        + callingPid + ", uid=" + callingUid
17819                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17820                Slog.w(TAG, msg);
17821                throw new SecurityException(msg);
17822            }
17823            if (requiredPermissions != null && requiredPermissions.length > 0) {
17824                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17825                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17826                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17827            }
17828            if (intent.getComponent() != null) {
17829                throw new SecurityException(
17830                        "Sticky broadcasts can't target a specific component");
17831            }
17832            // We use userId directly here, since the "all" target is maintained
17833            // as a separate set of sticky broadcasts.
17834            if (userId != UserHandle.USER_ALL) {
17835                // But first, if this is not a broadcast to all users, then
17836                // make sure it doesn't conflict with an existing broadcast to
17837                // all users.
17838                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17839                        UserHandle.USER_ALL);
17840                if (stickies != null) {
17841                    ArrayList<Intent> list = stickies.get(intent.getAction());
17842                    if (list != null) {
17843                        int N = list.size();
17844                        int i;
17845                        for (i=0; i<N; i++) {
17846                            if (intent.filterEquals(list.get(i))) {
17847                                throw new IllegalArgumentException(
17848                                        "Sticky broadcast " + intent + " for user "
17849                                        + userId + " conflicts with existing global broadcast");
17850                            }
17851                        }
17852                    }
17853                }
17854            }
17855            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17856            if (stickies == null) {
17857                stickies = new ArrayMap<>();
17858                mStickyBroadcasts.put(userId, stickies);
17859            }
17860            ArrayList<Intent> list = stickies.get(intent.getAction());
17861            if (list == null) {
17862                list = new ArrayList<>();
17863                stickies.put(intent.getAction(), list);
17864            }
17865            final int stickiesCount = list.size();
17866            int i;
17867            for (i = 0; i < stickiesCount; i++) {
17868                if (intent.filterEquals(list.get(i))) {
17869                    // This sticky already exists, replace it.
17870                    list.set(i, new Intent(intent));
17871                    break;
17872                }
17873            }
17874            if (i >= stickiesCount) {
17875                list.add(new Intent(intent));
17876            }
17877        }
17878
17879        int[] users;
17880        if (userId == UserHandle.USER_ALL) {
17881            // Caller wants broadcast to go to all started users.
17882            users = mUserController.getStartedUserArrayLocked();
17883        } else {
17884            // Caller wants broadcast to go to one specific user.
17885            users = new int[] {userId};
17886        }
17887
17888        // Figure out who all will receive this broadcast.
17889        List receivers = null;
17890        List<BroadcastFilter> registeredReceivers = null;
17891        // Need to resolve the intent to interested receivers...
17892        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17893                 == 0) {
17894            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17895        }
17896        if (intent.getComponent() == null) {
17897            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17898                // Query one target user at a time, excluding shell-restricted users
17899                for (int i = 0; i < users.length; i++) {
17900                    if (mUserController.hasUserRestriction(
17901                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17902                        continue;
17903                    }
17904                    List<BroadcastFilter> registeredReceiversForUser =
17905                            mReceiverResolver.queryIntent(intent,
17906                                    resolvedType, false, users[i]);
17907                    if (registeredReceivers == null) {
17908                        registeredReceivers = registeredReceiversForUser;
17909                    } else if (registeredReceiversForUser != null) {
17910                        registeredReceivers.addAll(registeredReceiversForUser);
17911                    }
17912                }
17913            } else {
17914                registeredReceivers = mReceiverResolver.queryIntent(intent,
17915                        resolvedType, false, userId);
17916            }
17917        }
17918
17919        final boolean replacePending =
17920                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17921
17922        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17923                + " replacePending=" + replacePending);
17924
17925        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17926        if (!ordered && NR > 0) {
17927            // If we are not serializing this broadcast, then send the
17928            // registered receivers separately so they don't wait for the
17929            // components to be launched.
17930            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17931            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17932                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17933                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17934                    resultExtras, ordered, sticky, false, userId);
17935            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17936            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17937            if (!replaced) {
17938                queue.enqueueParallelBroadcastLocked(r);
17939                queue.scheduleBroadcastsLocked();
17940            }
17941            registeredReceivers = null;
17942            NR = 0;
17943        }
17944
17945        // Merge into one list.
17946        int ir = 0;
17947        if (receivers != null) {
17948            // A special case for PACKAGE_ADDED: do not allow the package
17949            // being added to see this broadcast.  This prevents them from
17950            // using this as a back door to get run as soon as they are
17951            // installed.  Maybe in the future we want to have a special install
17952            // broadcast or such for apps, but we'd like to deliberately make
17953            // this decision.
17954            String skipPackages[] = null;
17955            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17956                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17957                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17958                Uri data = intent.getData();
17959                if (data != null) {
17960                    String pkgName = data.getSchemeSpecificPart();
17961                    if (pkgName != null) {
17962                        skipPackages = new String[] { pkgName };
17963                    }
17964                }
17965            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17966                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17967            }
17968            if (skipPackages != null && (skipPackages.length > 0)) {
17969                for (String skipPackage : skipPackages) {
17970                    if (skipPackage != null) {
17971                        int NT = receivers.size();
17972                        for (int it=0; it<NT; it++) {
17973                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17974                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17975                                receivers.remove(it);
17976                                it--;
17977                                NT--;
17978                            }
17979                        }
17980                    }
17981                }
17982            }
17983
17984            int NT = receivers != null ? receivers.size() : 0;
17985            int it = 0;
17986            ResolveInfo curt = null;
17987            BroadcastFilter curr = null;
17988            while (it < NT && ir < NR) {
17989                if (curt == null) {
17990                    curt = (ResolveInfo)receivers.get(it);
17991                }
17992                if (curr == null) {
17993                    curr = registeredReceivers.get(ir);
17994                }
17995                if (curr.getPriority() >= curt.priority) {
17996                    // Insert this broadcast record into the final list.
17997                    receivers.add(it, curr);
17998                    ir++;
17999                    curr = null;
18000                    it++;
18001                    NT++;
18002                } else {
18003                    // Skip to the next ResolveInfo in the final list.
18004                    it++;
18005                    curt = null;
18006                }
18007            }
18008        }
18009        while (ir < NR) {
18010            if (receivers == null) {
18011                receivers = new ArrayList();
18012            }
18013            receivers.add(registeredReceivers.get(ir));
18014            ir++;
18015        }
18016
18017        if ((receivers != null && receivers.size() > 0)
18018                || resultTo != null) {
18019            BroadcastQueue queue = broadcastQueueForIntent(intent);
18020            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18021                    callerPackage, callingPid, callingUid, resolvedType,
18022                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18023                    resultData, resultExtras, ordered, sticky, false, userId);
18024
18025            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18026                    + ": prev had " + queue.mOrderedBroadcasts.size());
18027            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18028                    "Enqueueing broadcast " + r.intent.getAction());
18029
18030            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18031            if (!replaced) {
18032                queue.enqueueOrderedBroadcastLocked(r);
18033                queue.scheduleBroadcastsLocked();
18034            }
18035        } else {
18036            // There was nobody interested in the broadcast, but we still want to record
18037            // that it happened.
18038            if (intent.getComponent() == null && intent.getPackage() == null
18039                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18040                // This was an implicit broadcast... let's record it for posterity.
18041                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18042            }
18043        }
18044
18045        return ActivityManager.BROADCAST_SUCCESS;
18046    }
18047
18048    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18049            int skipCount, long dispatchTime) {
18050        final long now = SystemClock.elapsedRealtime();
18051        if (mCurBroadcastStats == null ||
18052                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18053            mLastBroadcastStats = mCurBroadcastStats;
18054            if (mLastBroadcastStats != null) {
18055                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18056                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18057            }
18058            mCurBroadcastStats = new BroadcastStats();
18059        }
18060        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18061    }
18062
18063    final Intent verifyBroadcastLocked(Intent intent) {
18064        // Refuse possible leaked file descriptors
18065        if (intent != null && intent.hasFileDescriptors() == true) {
18066            throw new IllegalArgumentException("File descriptors passed in Intent");
18067        }
18068
18069        int flags = intent.getFlags();
18070
18071        if (!mProcessesReady) {
18072            // if the caller really truly claims to know what they're doing, go
18073            // ahead and allow the broadcast without launching any receivers
18074            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18075                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18076            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18077                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18078                        + " before boot completion");
18079                throw new IllegalStateException("Cannot broadcast before boot completed");
18080            }
18081        }
18082
18083        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18084            throw new IllegalArgumentException(
18085                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18086        }
18087
18088        return intent;
18089    }
18090
18091    public final int broadcastIntent(IApplicationThread caller,
18092            Intent intent, String resolvedType, IIntentReceiver resultTo,
18093            int resultCode, String resultData, Bundle resultExtras,
18094            String[] requiredPermissions, int appOp, Bundle bOptions,
18095            boolean serialized, boolean sticky, int userId) {
18096        enforceNotIsolatedCaller("broadcastIntent");
18097        synchronized(this) {
18098            intent = verifyBroadcastLocked(intent);
18099
18100            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18101            final int callingPid = Binder.getCallingPid();
18102            final int callingUid = Binder.getCallingUid();
18103            final long origId = Binder.clearCallingIdentity();
18104            int res = broadcastIntentLocked(callerApp,
18105                    callerApp != null ? callerApp.info.packageName : null,
18106                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18107                    requiredPermissions, appOp, bOptions, serialized, sticky,
18108                    callingPid, callingUid, userId);
18109            Binder.restoreCallingIdentity(origId);
18110            return res;
18111        }
18112    }
18113
18114
18115    int broadcastIntentInPackage(String packageName, int uid,
18116            Intent intent, String resolvedType, IIntentReceiver resultTo,
18117            int resultCode, String resultData, Bundle resultExtras,
18118            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18119            int userId) {
18120        synchronized(this) {
18121            intent = verifyBroadcastLocked(intent);
18122
18123            final long origId = Binder.clearCallingIdentity();
18124            String[] requiredPermissions = requiredPermission == null ? null
18125                    : new String[] {requiredPermission};
18126            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18127                    resultTo, resultCode, resultData, resultExtras,
18128                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18129                    sticky, -1, uid, userId);
18130            Binder.restoreCallingIdentity(origId);
18131            return res;
18132        }
18133    }
18134
18135    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18136        // Refuse possible leaked file descriptors
18137        if (intent != null && intent.hasFileDescriptors() == true) {
18138            throw new IllegalArgumentException("File descriptors passed in Intent");
18139        }
18140
18141        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18142                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18143
18144        synchronized(this) {
18145            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18146                    != PackageManager.PERMISSION_GRANTED) {
18147                String msg = "Permission Denial: unbroadcastIntent() from pid="
18148                        + Binder.getCallingPid()
18149                        + ", uid=" + Binder.getCallingUid()
18150                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18151                Slog.w(TAG, msg);
18152                throw new SecurityException(msg);
18153            }
18154            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18155            if (stickies != null) {
18156                ArrayList<Intent> list = stickies.get(intent.getAction());
18157                if (list != null) {
18158                    int N = list.size();
18159                    int i;
18160                    for (i=0; i<N; i++) {
18161                        if (intent.filterEquals(list.get(i))) {
18162                            list.remove(i);
18163                            break;
18164                        }
18165                    }
18166                    if (list.size() <= 0) {
18167                        stickies.remove(intent.getAction());
18168                    }
18169                }
18170                if (stickies.size() <= 0) {
18171                    mStickyBroadcasts.remove(userId);
18172                }
18173            }
18174        }
18175    }
18176
18177    void backgroundServicesFinishedLocked(int userId) {
18178        for (BroadcastQueue queue : mBroadcastQueues) {
18179            queue.backgroundServicesFinishedLocked(userId);
18180        }
18181    }
18182
18183    public void finishReceiver(IBinder who, int resultCode, String resultData,
18184            Bundle resultExtras, boolean resultAbort, int flags) {
18185        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18186
18187        // Refuse possible leaked file descriptors
18188        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18189            throw new IllegalArgumentException("File descriptors passed in Bundle");
18190        }
18191
18192        final long origId = Binder.clearCallingIdentity();
18193        try {
18194            boolean doNext = false;
18195            BroadcastRecord r;
18196
18197            synchronized(this) {
18198                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18199                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18200                r = queue.getMatchingOrderedReceiver(who);
18201                if (r != null) {
18202                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18203                        resultData, resultExtras, resultAbort, true);
18204                }
18205            }
18206
18207            if (doNext) {
18208                r.queue.processNextBroadcast(false);
18209            }
18210            trimApplications();
18211        } finally {
18212            Binder.restoreCallingIdentity(origId);
18213        }
18214    }
18215
18216    // =========================================================
18217    // INSTRUMENTATION
18218    // =========================================================
18219
18220    public boolean startInstrumentation(ComponentName className,
18221            String profileFile, int flags, Bundle arguments,
18222            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18223            int userId, String abiOverride) {
18224        enforceNotIsolatedCaller("startInstrumentation");
18225        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18226                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18227        // Refuse possible leaked file descriptors
18228        if (arguments != null && arguments.hasFileDescriptors()) {
18229            throw new IllegalArgumentException("File descriptors passed in Bundle");
18230        }
18231
18232        synchronized(this) {
18233            InstrumentationInfo ii = null;
18234            ApplicationInfo ai = null;
18235            try {
18236                ii = mContext.getPackageManager().getInstrumentationInfo(
18237                    className, STOCK_PM_FLAGS);
18238                ai = AppGlobals.getPackageManager().getApplicationInfo(
18239                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18240            } catch (PackageManager.NameNotFoundException e) {
18241            } catch (RemoteException e) {
18242            }
18243            if (ii == null) {
18244                reportStartInstrumentationFailureLocked(watcher, className,
18245                        "Unable to find instrumentation info for: " + className);
18246                return false;
18247            }
18248            if (ai == null) {
18249                reportStartInstrumentationFailureLocked(watcher, className,
18250                        "Unable to find instrumentation target package: " + ii.targetPackage);
18251                return false;
18252            }
18253            if (!ai.hasCode()) {
18254                reportStartInstrumentationFailureLocked(watcher, className,
18255                        "Instrumentation target has no code: " + ii.targetPackage);
18256                return false;
18257            }
18258
18259            int match = mContext.getPackageManager().checkSignatures(
18260                    ii.targetPackage, ii.packageName);
18261            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18262                String msg = "Permission Denial: starting instrumentation "
18263                        + className + " from pid="
18264                        + Binder.getCallingPid()
18265                        + ", uid=" + Binder.getCallingPid()
18266                        + " not allowed because package " + ii.packageName
18267                        + " does not have a signature matching the target "
18268                        + ii.targetPackage;
18269                reportStartInstrumentationFailureLocked(watcher, className, msg);
18270                throw new SecurityException(msg);
18271            }
18272
18273            final long origId = Binder.clearCallingIdentity();
18274            // Instrumentation can kill and relaunch even persistent processes
18275            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18276                    "start instr");
18277            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18278            app.instrumentationClass = className;
18279            app.instrumentationInfo = ai;
18280            app.instrumentationProfileFile = profileFile;
18281            app.instrumentationArguments = arguments;
18282            app.instrumentationWatcher = watcher;
18283            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18284            app.instrumentationResultClass = className;
18285            Binder.restoreCallingIdentity(origId);
18286        }
18287
18288        return true;
18289    }
18290
18291    /**
18292     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18293     * error to the logs, but if somebody is watching, send the report there too.  This enables
18294     * the "am" command to report errors with more information.
18295     *
18296     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18297     * @param cn The component name of the instrumentation.
18298     * @param report The error report.
18299     */
18300    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18301            ComponentName cn, String report) {
18302        Slog.w(TAG, report);
18303        if (watcher != null) {
18304            Bundle results = new Bundle();
18305            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18306            results.putString("Error", report);
18307            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18308        }
18309    }
18310
18311    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18312        if (app.instrumentationWatcher != null) {
18313            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18314                    app.instrumentationClass, resultCode, results);
18315        }
18316
18317        // Can't call out of the system process with a lock held, so post a message.
18318        if (app.instrumentationUiAutomationConnection != null) {
18319            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18320                    app.instrumentationUiAutomationConnection).sendToTarget();
18321        }
18322
18323        app.instrumentationWatcher = null;
18324        app.instrumentationUiAutomationConnection = null;
18325        app.instrumentationClass = null;
18326        app.instrumentationInfo = null;
18327        app.instrumentationProfileFile = null;
18328        app.instrumentationArguments = null;
18329
18330        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18331                "finished inst");
18332    }
18333
18334    public void finishInstrumentation(IApplicationThread target,
18335            int resultCode, Bundle results) {
18336        int userId = UserHandle.getCallingUserId();
18337        // Refuse possible leaked file descriptors
18338        if (results != null && results.hasFileDescriptors()) {
18339            throw new IllegalArgumentException("File descriptors passed in Intent");
18340        }
18341
18342        synchronized(this) {
18343            ProcessRecord app = getRecordForAppLocked(target);
18344            if (app == null) {
18345                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18346                return;
18347            }
18348            final long origId = Binder.clearCallingIdentity();
18349            finishInstrumentationLocked(app, resultCode, results);
18350            Binder.restoreCallingIdentity(origId);
18351        }
18352    }
18353
18354    // =========================================================
18355    // CONFIGURATION
18356    // =========================================================
18357
18358    public ConfigurationInfo getDeviceConfigurationInfo() {
18359        ConfigurationInfo config = new ConfigurationInfo();
18360        synchronized (this) {
18361            config.reqTouchScreen = mConfiguration.touchscreen;
18362            config.reqKeyboardType = mConfiguration.keyboard;
18363            config.reqNavigation = mConfiguration.navigation;
18364            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18365                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18366                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18367            }
18368            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18369                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18370                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18371            }
18372            config.reqGlEsVersion = GL_ES_VERSION;
18373        }
18374        return config;
18375    }
18376
18377    ActivityStack getFocusedStack() {
18378        return mStackSupervisor.getFocusedStack();
18379    }
18380
18381    @Override
18382    public int getFocusedStackId() throws RemoteException {
18383        ActivityStack focusedStack = getFocusedStack();
18384        if (focusedStack != null) {
18385            return focusedStack.getStackId();
18386        }
18387        return -1;
18388    }
18389
18390    public Configuration getConfiguration() {
18391        Configuration ci;
18392        synchronized(this) {
18393            ci = new Configuration(mConfiguration);
18394            ci.userSetLocale = false;
18395        }
18396        return ci;
18397    }
18398
18399    @Override
18400    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18401        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18402        synchronized (this) {
18403            mSuppressResizeConfigChanges = suppress;
18404        }
18405    }
18406
18407    @Override
18408    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18410        if (fromStackId == HOME_STACK_ID) {
18411            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18412        }
18413        synchronized (this) {
18414            final long origId = Binder.clearCallingIdentity();
18415            try {
18416                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18417            } finally {
18418                Binder.restoreCallingIdentity(origId);
18419            }
18420        }
18421    }
18422
18423    @Override
18424    public void updatePersistentConfiguration(Configuration values) {
18425        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18426                "updateConfiguration()");
18427        enforceWriteSettingsPermission("updateConfiguration()");
18428        if (values == null) {
18429            throw new NullPointerException("Configuration must not be null");
18430        }
18431
18432        int userId = UserHandle.getCallingUserId();
18433
18434        synchronized(this) {
18435            final long origId = Binder.clearCallingIdentity();
18436            updateConfigurationLocked(values, null, false, true, userId);
18437            Binder.restoreCallingIdentity(origId);
18438        }
18439    }
18440
18441    private void updateFontScaleIfNeeded() {
18442        final int currentUserId;
18443        synchronized(this) {
18444            currentUserId = mUserController.getCurrentUserIdLocked();
18445        }
18446        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18447                FONT_SCALE, 1.0f, currentUserId);
18448        if (mConfiguration.fontScale != scaleFactor) {
18449            final Configuration configuration = mWindowManager.computeNewConfiguration();
18450            configuration.fontScale = scaleFactor;
18451            updatePersistentConfiguration(configuration);
18452        }
18453    }
18454
18455    private void enforceWriteSettingsPermission(String func) {
18456        int uid = Binder.getCallingUid();
18457        if (uid == Process.ROOT_UID) {
18458            return;
18459        }
18460
18461        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18462                Settings.getPackageNameForUid(mContext, uid), false)) {
18463            return;
18464        }
18465
18466        String msg = "Permission Denial: " + func + " from pid="
18467                + Binder.getCallingPid()
18468                + ", uid=" + uid
18469                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18470        Slog.w(TAG, msg);
18471        throw new SecurityException(msg);
18472    }
18473
18474    public void updateConfiguration(Configuration values) {
18475        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18476                "updateConfiguration()");
18477
18478        synchronized(this) {
18479            if (values == null && mWindowManager != null) {
18480                // sentinel: fetch the current configuration from the window manager
18481                values = mWindowManager.computeNewConfiguration();
18482            }
18483
18484            if (mWindowManager != null) {
18485                mProcessList.applyDisplaySize(mWindowManager);
18486            }
18487
18488            final long origId = Binder.clearCallingIdentity();
18489            if (values != null) {
18490                Settings.System.clearConfiguration(values);
18491            }
18492            updateConfigurationLocked(values, null, false);
18493            Binder.restoreCallingIdentity(origId);
18494        }
18495    }
18496
18497    void updateUserConfigurationLocked() {
18498        Configuration configuration = new Configuration(mConfiguration);
18499        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18500                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18501        updateConfigurationLocked(configuration, null, false);
18502    }
18503
18504    boolean updateConfigurationLocked(Configuration values,
18505            ActivityRecord starting, boolean initLocale) {
18506        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18507        return updateConfigurationLocked(values, starting, initLocale, false,
18508                UserHandle.USER_NULL);
18509    }
18510
18511    // To cache the list of supported system locales
18512    private String[] mSupportedSystemLocales = null;
18513
18514    /**
18515     * Do either or both things: (1) change the current configuration, and (2)
18516     * make sure the given activity is running with the (now) current
18517     * configuration.  Returns true if the activity has been left running, or
18518     * false if <var>starting</var> is being destroyed to match the new
18519     * configuration.
18520     *
18521     * @param userId is only used when persistent parameter is set to true to persist configuration
18522     *               for that particular user
18523     */
18524    private boolean updateConfigurationLocked(Configuration values,
18525            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18526        int changes = 0;
18527
18528        if (mWindowManager != null) {
18529            mWindowManager.deferSurfaceLayout();
18530        }
18531        if (values != null) {
18532            Configuration newConfig = new Configuration(mConfiguration);
18533            changes = newConfig.updateFrom(values);
18534            if (changes != 0) {
18535                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18536                        "Updating configuration to: " + values);
18537
18538                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18539
18540                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18541                    final LocaleList locales = values.getLocales();
18542                    int bestLocaleIndex = 0;
18543                    if (locales.size() > 1) {
18544                        if (mSupportedSystemLocales == null) {
18545                            mSupportedSystemLocales =
18546                                    Resources.getSystem().getAssets().getLocales();
18547                        }
18548                        bestLocaleIndex = Math.max(0,
18549                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18550                    }
18551                    SystemProperties.set("persist.sys.locale",
18552                            locales.get(bestLocaleIndex).toLanguageTag());
18553                    LocaleList.setDefault(locales, bestLocaleIndex);
18554                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18555                            locales.get(bestLocaleIndex)));
18556                }
18557
18558                mConfigurationSeq++;
18559                if (mConfigurationSeq <= 0) {
18560                    mConfigurationSeq = 1;
18561                }
18562                newConfig.seq = mConfigurationSeq;
18563                mConfiguration = newConfig;
18564                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18565                mUsageStatsService.reportConfigurationChange(newConfig,
18566                        mUserController.getCurrentUserIdLocked());
18567                //mUsageStatsService.noteStartConfig(newConfig);
18568
18569                final Configuration configCopy = new Configuration(mConfiguration);
18570
18571                // TODO: If our config changes, should we auto dismiss any currently
18572                // showing dialogs?
18573                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18574
18575                AttributeCache ac = AttributeCache.instance();
18576                if (ac != null) {
18577                    ac.updateConfiguration(configCopy);
18578                }
18579
18580                // Make sure all resources in our process are updated
18581                // right now, so that anyone who is going to retrieve
18582                // resource values after we return will be sure to get
18583                // the new ones.  This is especially important during
18584                // boot, where the first config change needs to guarantee
18585                // all resources have that config before following boot
18586                // code is executed.
18587                mSystemThread.applyConfigurationToResources(configCopy);
18588
18589                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18590                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18591                    msg.obj = new Configuration(configCopy);
18592                    msg.arg1 = userId;
18593                    mHandler.sendMessage(msg);
18594                }
18595
18596                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18597                if (isDensityChange) {
18598                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18599                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18600                }
18601
18602                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18603                    ProcessRecord app = mLruProcesses.get(i);
18604                    try {
18605                        if (app.thread != null) {
18606                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18607                                    + app.processName + " new config " + mConfiguration);
18608                            app.thread.scheduleConfigurationChanged(configCopy);
18609                        }
18610                    } catch (Exception e) {
18611                    }
18612                }
18613                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18614                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18615                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18616                        | Intent.FLAG_RECEIVER_FOREGROUND);
18617                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18618                        null, AppOpsManager.OP_NONE, null, false, false,
18619                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18620                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18621                    // Tell the shortcut manager that the system locale changed.  It needs to know
18622                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18623                    // we "push" from here, rather than having the service listen to the broadcast.
18624                    final ShortcutServiceInternal shortcutService =
18625                            LocalServices.getService(ShortcutServiceInternal.class);
18626                    if (shortcutService != null) {
18627                        shortcutService.onSystemLocaleChangedNoLock();
18628                    }
18629
18630                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18631                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18632                    if (!mProcessesReady) {
18633                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18634                    }
18635                    broadcastIntentLocked(null, null, intent,
18636                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18637                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18638                }
18639            }
18640            // Update the configuration with WM first and check if any of the stacks need to be
18641            // resized due to the configuration change. If so, resize the stacks now and do any
18642            // relaunches if necessary. This way we don't need to relaunch again below in
18643            // ensureActivityConfigurationLocked().
18644            if (mWindowManager != null) {
18645                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18646                if (resizedStacks != null) {
18647                    for (int stackId : resizedStacks) {
18648                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18649                        mStackSupervisor.resizeStackLocked(
18650                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18651                    }
18652                }
18653            }
18654        }
18655
18656        boolean kept = true;
18657        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18658        // mainStack is null during startup.
18659        if (mainStack != null) {
18660            if (changes != 0 && starting == null) {
18661                // If the configuration changed, and the caller is not already
18662                // in the process of starting an activity, then find the top
18663                // activity to check if its configuration needs to change.
18664                starting = mainStack.topRunningActivityLocked();
18665            }
18666
18667            if (starting != null) {
18668                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18669                // And we need to make sure at this point that all other activities
18670                // are made visible with the correct configuration.
18671                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18672                        !PRESERVE_WINDOWS);
18673            }
18674        }
18675        if (mWindowManager != null) {
18676            mWindowManager.continueSurfaceLayout();
18677        }
18678        return kept;
18679    }
18680
18681    /**
18682     * Decide based on the configuration whether we should shouw the ANR,
18683     * crash, etc dialogs.  The idea is that if there is no affordnace to
18684     * press the on-screen buttons, we shouldn't show the dialog.
18685     *
18686     * A thought: SystemUI might also want to get told about this, the Power
18687     * dialog / global actions also might want different behaviors.
18688     */
18689    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18690        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18691                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18692                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18693        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18694                                    == Configuration.UI_MODE_TYPE_CAR);
18695        return inputMethodExists && uiIsNotCarType && !inVrMode;
18696    }
18697
18698    @Override
18699    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18700        synchronized (this) {
18701            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18702            if (srec != null) {
18703                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18704            }
18705        }
18706        return false;
18707    }
18708
18709    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18710            Intent resultData) {
18711
18712        synchronized (this) {
18713            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18714            if (r != null) {
18715                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18716            }
18717            return false;
18718        }
18719    }
18720
18721    public int getLaunchedFromUid(IBinder activityToken) {
18722        ActivityRecord srec;
18723        synchronized (this) {
18724            srec = ActivityRecord.forTokenLocked(activityToken);
18725        }
18726        if (srec == null) {
18727            return -1;
18728        }
18729        return srec.launchedFromUid;
18730    }
18731
18732    public String getLaunchedFromPackage(IBinder activityToken) {
18733        ActivityRecord srec;
18734        synchronized (this) {
18735            srec = ActivityRecord.forTokenLocked(activityToken);
18736        }
18737        if (srec == null) {
18738            return null;
18739        }
18740        return srec.launchedFromPackage;
18741    }
18742
18743    // =========================================================
18744    // LIFETIME MANAGEMENT
18745    // =========================================================
18746
18747    // Returns which broadcast queue the app is the current [or imminent] receiver
18748    // on, or 'null' if the app is not an active broadcast recipient.
18749    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18750        BroadcastRecord r = app.curReceiver;
18751        if (r != null) {
18752            return r.queue;
18753        }
18754
18755        // It's not the current receiver, but it might be starting up to become one
18756        synchronized (this) {
18757            for (BroadcastQueue queue : mBroadcastQueues) {
18758                r = queue.mPendingBroadcast;
18759                if (r != null && r.curApp == app) {
18760                    // found it; report which queue it's in
18761                    return queue;
18762                }
18763            }
18764        }
18765
18766        return null;
18767    }
18768
18769    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18770            int targetUid, ComponentName targetComponent, String targetProcess) {
18771        if (!mTrackingAssociations) {
18772            return null;
18773        }
18774        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18775                = mAssociations.get(targetUid);
18776        if (components == null) {
18777            components = new ArrayMap<>();
18778            mAssociations.put(targetUid, components);
18779        }
18780        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18781        if (sourceUids == null) {
18782            sourceUids = new SparseArray<>();
18783            components.put(targetComponent, sourceUids);
18784        }
18785        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18786        if (sourceProcesses == null) {
18787            sourceProcesses = new ArrayMap<>();
18788            sourceUids.put(sourceUid, sourceProcesses);
18789        }
18790        Association ass = sourceProcesses.get(sourceProcess);
18791        if (ass == null) {
18792            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18793                    targetProcess);
18794            sourceProcesses.put(sourceProcess, ass);
18795        }
18796        ass.mCount++;
18797        ass.mNesting++;
18798        if (ass.mNesting == 1) {
18799            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18800            ass.mLastState = sourceState;
18801        }
18802        return ass;
18803    }
18804
18805    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18806            ComponentName targetComponent) {
18807        if (!mTrackingAssociations) {
18808            return;
18809        }
18810        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18811                = mAssociations.get(targetUid);
18812        if (components == null) {
18813            return;
18814        }
18815        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18816        if (sourceUids == null) {
18817            return;
18818        }
18819        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18820        if (sourceProcesses == null) {
18821            return;
18822        }
18823        Association ass = sourceProcesses.get(sourceProcess);
18824        if (ass == null || ass.mNesting <= 0) {
18825            return;
18826        }
18827        ass.mNesting--;
18828        if (ass.mNesting == 0) {
18829            long uptime = SystemClock.uptimeMillis();
18830            ass.mTime += uptime - ass.mStartTime;
18831            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18832                    += uptime - ass.mLastStateUptime;
18833            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18834        }
18835    }
18836
18837    private void noteUidProcessState(final int uid, final int state) {
18838        mBatteryStatsService.noteUidProcessState(uid, state);
18839        if (mTrackingAssociations) {
18840            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18841                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18842                        = mAssociations.valueAt(i1);
18843                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18844                    SparseArray<ArrayMap<String, Association>> sourceUids
18845                            = targetComponents.valueAt(i2);
18846                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18847                    if (sourceProcesses != null) {
18848                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18849                            Association ass = sourceProcesses.valueAt(i4);
18850                            if (ass.mNesting >= 1) {
18851                                // currently associated
18852                                long uptime = SystemClock.uptimeMillis();
18853                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18854                                        += uptime - ass.mLastStateUptime;
18855                                ass.mLastState = state;
18856                                ass.mLastStateUptime = uptime;
18857                            }
18858                        }
18859                    }
18860                }
18861            }
18862        }
18863    }
18864
18865    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18866            boolean doingAll, long now) {
18867        if (mAdjSeq == app.adjSeq) {
18868            // This adjustment has already been computed.
18869            return app.curRawAdj;
18870        }
18871
18872        if (app.thread == null) {
18873            app.adjSeq = mAdjSeq;
18874            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18875            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18876            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18877        }
18878
18879        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18880        app.adjSource = null;
18881        app.adjTarget = null;
18882        app.empty = false;
18883        app.cached = false;
18884
18885        final int activitiesSize = app.activities.size();
18886
18887        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18888            // The max adjustment doesn't allow this app to be anything
18889            // below foreground, so it is not worth doing work for it.
18890            app.adjType = "fixed";
18891            app.adjSeq = mAdjSeq;
18892            app.curRawAdj = app.maxAdj;
18893            app.foregroundActivities = false;
18894            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18895            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18896            // System processes can do UI, and when they do we want to have
18897            // them trim their memory after the user leaves the UI.  To
18898            // facilitate this, here we need to determine whether or not it
18899            // is currently showing UI.
18900            app.systemNoUi = true;
18901            if (app == TOP_APP) {
18902                app.systemNoUi = false;
18903                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18904                app.adjType = "pers-top-activity";
18905            } else if (activitiesSize > 0) {
18906                for (int j = 0; j < activitiesSize; j++) {
18907                    final ActivityRecord r = app.activities.get(j);
18908                    if (r.visible) {
18909                        app.systemNoUi = false;
18910                    }
18911                }
18912            }
18913            if (!app.systemNoUi) {
18914                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18915            }
18916            return (app.curAdj=app.maxAdj);
18917        }
18918
18919        app.systemNoUi = false;
18920
18921        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18922
18923        // Determine the importance of the process, starting with most
18924        // important to least, and assign an appropriate OOM adjustment.
18925        int adj;
18926        int schedGroup;
18927        int procState;
18928        boolean foregroundActivities = false;
18929        BroadcastQueue queue;
18930        if (app == TOP_APP) {
18931            // The last app on the list is the foreground app.
18932            adj = ProcessList.FOREGROUND_APP_ADJ;
18933            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18934            app.adjType = "top-activity";
18935            foregroundActivities = true;
18936            procState = PROCESS_STATE_CUR_TOP;
18937        } else if (app.instrumentationClass != null) {
18938            // Don't want to kill running instrumentation.
18939            adj = ProcessList.FOREGROUND_APP_ADJ;
18940            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18941            app.adjType = "instrumentation";
18942            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18943        } else if ((queue = isReceivingBroadcast(app)) != null) {
18944            // An app that is currently receiving a broadcast also
18945            // counts as being in the foreground for OOM killer purposes.
18946            // It's placed in a sched group based on the nature of the
18947            // broadcast as reflected by which queue it's active in.
18948            adj = ProcessList.FOREGROUND_APP_ADJ;
18949            schedGroup = (queue == mFgBroadcastQueue)
18950                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18951            app.adjType = "broadcast";
18952            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18953        } else if (app.executingServices.size() > 0) {
18954            // An app that is currently executing a service callback also
18955            // counts as being in the foreground.
18956            adj = ProcessList.FOREGROUND_APP_ADJ;
18957            schedGroup = app.execServicesFg ?
18958                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18959            app.adjType = "exec-service";
18960            procState = ActivityManager.PROCESS_STATE_SERVICE;
18961            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18962        } else {
18963            // As far as we know the process is empty.  We may change our mind later.
18964            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18965            // At this point we don't actually know the adjustment.  Use the cached adj
18966            // value that the caller wants us to.
18967            adj = cachedAdj;
18968            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18969            app.cached = true;
18970            app.empty = true;
18971            app.adjType = "cch-empty";
18972        }
18973
18974        // Examine all activities if not already foreground.
18975        if (!foregroundActivities && activitiesSize > 0) {
18976            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18977            for (int j = 0; j < activitiesSize; j++) {
18978                final ActivityRecord r = app.activities.get(j);
18979                if (r.app != app) {
18980                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
18981                            + " instead of expected " + app);
18982                    if (r.app == null || (r.app.uid == app.uid)) {
18983                        // Only fix things up when they look sane
18984                        r.app = app;
18985                    } else {
18986                        continue;
18987                    }
18988                }
18989                if (r.visible) {
18990                    // App has a visible activity; only upgrade adjustment.
18991                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18992                        adj = ProcessList.VISIBLE_APP_ADJ;
18993                        app.adjType = "visible";
18994                    }
18995                    if (procState > PROCESS_STATE_CUR_TOP) {
18996                        procState = PROCESS_STATE_CUR_TOP;
18997                    }
18998                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18999                    app.cached = false;
19000                    app.empty = false;
19001                    foregroundActivities = true;
19002                    if (r.task != null && minLayer > 0) {
19003                        final int layer = r.task.mLayerRank;
19004                        if (layer >= 0 && minLayer > layer) {
19005                            minLayer = layer;
19006                        }
19007                    }
19008                    break;
19009                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19010                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19011                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19012                        app.adjType = "pausing";
19013                    }
19014                    if (procState > PROCESS_STATE_CUR_TOP) {
19015                        procState = PROCESS_STATE_CUR_TOP;
19016                    }
19017                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19018                    app.cached = false;
19019                    app.empty = false;
19020                    foregroundActivities = true;
19021                } else if (r.state == ActivityState.STOPPING) {
19022                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19023                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19024                        app.adjType = "stopping";
19025                    }
19026                    // For the process state, we will at this point consider the
19027                    // process to be cached.  It will be cached either as an activity
19028                    // or empty depending on whether the activity is finishing.  We do
19029                    // this so that we can treat the process as cached for purposes of
19030                    // memory trimming (determing current memory level, trim command to
19031                    // send to process) since there can be an arbitrary number of stopping
19032                    // processes and they should soon all go into the cached state.
19033                    if (!r.finishing) {
19034                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19035                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19036                        }
19037                    }
19038                    app.cached = false;
19039                    app.empty = false;
19040                    foregroundActivities = true;
19041                } else {
19042                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19043                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19044                        app.adjType = "cch-act";
19045                    }
19046                }
19047            }
19048            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19049                adj += minLayer;
19050            }
19051        }
19052
19053        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19054                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19055            if (app.foregroundServices) {
19056                // The user is aware of this app, so make it visible.
19057                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19058                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19059                app.cached = false;
19060                app.adjType = "fg-service";
19061                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19062            } else if (app.forcingToForeground != null) {
19063                // The user is aware of this app, so make it visible.
19064                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19065                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19066                app.cached = false;
19067                app.adjType = "force-fg";
19068                app.adjSource = app.forcingToForeground;
19069                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19070            }
19071        }
19072
19073        if (app == mHeavyWeightProcess) {
19074            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19075                // We don't want to kill the current heavy-weight process.
19076                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19077                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19078                app.cached = false;
19079                app.adjType = "heavy";
19080            }
19081            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19082                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19083            }
19084        }
19085
19086        if (app == mHomeProcess) {
19087            if (adj > ProcessList.HOME_APP_ADJ) {
19088                // This process is hosting what we currently consider to be the
19089                // home app, so we don't want to let it go into the background.
19090                adj = ProcessList.HOME_APP_ADJ;
19091                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19092                app.cached = false;
19093                app.adjType = "home";
19094            }
19095            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19096                procState = ActivityManager.PROCESS_STATE_HOME;
19097            }
19098        }
19099
19100        if (app == mPreviousProcess && app.activities.size() > 0) {
19101            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19102                // This was the previous process that showed UI to the user.
19103                // We want to try to keep it around more aggressively, to give
19104                // a good experience around switching between two apps.
19105                adj = ProcessList.PREVIOUS_APP_ADJ;
19106                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19107                app.cached = false;
19108                app.adjType = "previous";
19109            }
19110            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19111                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19112            }
19113        }
19114
19115        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19116                + " reason=" + app.adjType);
19117
19118        // By default, we use the computed adjustment.  It may be changed if
19119        // there are applications dependent on our services or providers, but
19120        // this gives us a baseline and makes sure we don't get into an
19121        // infinite recursion.
19122        app.adjSeq = mAdjSeq;
19123        app.curRawAdj = adj;
19124        app.hasStartedServices = false;
19125
19126        if (mBackupTarget != null && app == mBackupTarget.app) {
19127            // If possible we want to avoid killing apps while they're being backed up
19128            if (adj > ProcessList.BACKUP_APP_ADJ) {
19129                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19130                adj = ProcessList.BACKUP_APP_ADJ;
19131                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19132                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19133                }
19134                app.adjType = "backup";
19135                app.cached = false;
19136            }
19137            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19138                procState = ActivityManager.PROCESS_STATE_BACKUP;
19139            }
19140        }
19141
19142        boolean mayBeTop = false;
19143
19144        for (int is = app.services.size()-1;
19145                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19146                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19147                        || procState > ActivityManager.PROCESS_STATE_TOP);
19148                is--) {
19149            ServiceRecord s = app.services.valueAt(is);
19150            if (s.startRequested) {
19151                app.hasStartedServices = true;
19152                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19153                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19154                }
19155                if (app.hasShownUi && app != mHomeProcess) {
19156                    // If this process has shown some UI, let it immediately
19157                    // go to the LRU list because it may be pretty heavy with
19158                    // UI stuff.  We'll tag it with a label just to help
19159                    // debug and understand what is going on.
19160                    if (adj > ProcessList.SERVICE_ADJ) {
19161                        app.adjType = "cch-started-ui-services";
19162                    }
19163                } else {
19164                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19165                        // This service has seen some activity within
19166                        // recent memory, so we will keep its process ahead
19167                        // of the background processes.
19168                        if (adj > ProcessList.SERVICE_ADJ) {
19169                            adj = ProcessList.SERVICE_ADJ;
19170                            app.adjType = "started-services";
19171                            app.cached = false;
19172                        }
19173                    }
19174                    // If we have let the service slide into the background
19175                    // state, still have some text describing what it is doing
19176                    // even though the service no longer has an impact.
19177                    if (adj > ProcessList.SERVICE_ADJ) {
19178                        app.adjType = "cch-started-services";
19179                    }
19180                }
19181            }
19182
19183            app.whitelistManager = false;
19184
19185            for (int conni = s.connections.size()-1;
19186                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19187                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19188                            || procState > ActivityManager.PROCESS_STATE_TOP);
19189                    conni--) {
19190                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19191                for (int i = 0;
19192                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19193                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19194                                || procState > ActivityManager.PROCESS_STATE_TOP);
19195                        i++) {
19196                    // XXX should compute this based on the max of
19197                    // all connected clients.
19198                    ConnectionRecord cr = clist.get(i);
19199                    if (cr.binding.client == app) {
19200                        // Binding to ourself is not interesting.
19201                        continue;
19202                    }
19203                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19204                        app.whitelistManager = true;
19205                    }
19206
19207                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19208                        ProcessRecord client = cr.binding.client;
19209                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19210                                TOP_APP, doingAll, now);
19211                        int clientProcState = client.curProcState;
19212                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19213                            // If the other app is cached for any reason, for purposes here
19214                            // we are going to consider it empty.  The specific cached state
19215                            // doesn't propagate except under certain conditions.
19216                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19217                        }
19218                        String adjType = null;
19219                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19220                            // Not doing bind OOM management, so treat
19221                            // this guy more like a started service.
19222                            if (app.hasShownUi && app != mHomeProcess) {
19223                                // If this process has shown some UI, let it immediately
19224                                // go to the LRU list because it may be pretty heavy with
19225                                // UI stuff.  We'll tag it with a label just to help
19226                                // debug and understand what is going on.
19227                                if (adj > clientAdj) {
19228                                    adjType = "cch-bound-ui-services";
19229                                }
19230                                app.cached = false;
19231                                clientAdj = adj;
19232                                clientProcState = procState;
19233                            } else {
19234                                if (now >= (s.lastActivity
19235                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19236                                    // This service has not seen activity within
19237                                    // recent memory, so allow it to drop to the
19238                                    // LRU list if there is no other reason to keep
19239                                    // it around.  We'll also tag it with a label just
19240                                    // to help debug and undertand what is going on.
19241                                    if (adj > clientAdj) {
19242                                        adjType = "cch-bound-services";
19243                                    }
19244                                    clientAdj = adj;
19245                                }
19246                            }
19247                        }
19248                        if (adj > clientAdj) {
19249                            // If this process has recently shown UI, and
19250                            // the process that is binding to it is less
19251                            // important than being visible, then we don't
19252                            // care about the binding as much as we care
19253                            // about letting this process get into the LRU
19254                            // list to be killed and restarted if needed for
19255                            // memory.
19256                            if (app.hasShownUi && app != mHomeProcess
19257                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19258                                adjType = "cch-bound-ui-services";
19259                            } else {
19260                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19261                                        |Context.BIND_IMPORTANT)) != 0) {
19262                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19263                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19264                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19265                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19266                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19267                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19268                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19269                                    adj = clientAdj;
19270                                } else {
19271                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19272                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19273                                    }
19274                                }
19275                                if (!client.cached) {
19276                                    app.cached = false;
19277                                }
19278                                adjType = "service";
19279                            }
19280                        }
19281                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19282                            // This will treat important bound services identically to
19283                            // the top app, which may behave differently than generic
19284                            // foreground work.
19285                            if (client.curSchedGroup > schedGroup) {
19286                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19287                                    schedGroup = client.curSchedGroup;
19288                                } else {
19289                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19290                                }
19291                            }
19292                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19293                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19294                                    // Special handling of clients who are in the top state.
19295                                    // We *may* want to consider this process to be in the
19296                                    // top state as well, but only if there is not another
19297                                    // reason for it to be running.  Being on the top is a
19298                                    // special state, meaning you are specifically running
19299                                    // for the current top app.  If the process is already
19300                                    // running in the background for some other reason, it
19301                                    // is more important to continue considering it to be
19302                                    // in the background state.
19303                                    mayBeTop = true;
19304                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19305                                } else {
19306                                    // Special handling for above-top states (persistent
19307                                    // processes).  These should not bring the current process
19308                                    // into the top state, since they are not on top.  Instead
19309                                    // give them the best state after that.
19310                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19311                                        clientProcState =
19312                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19313                                    } else if (mWakefulness
19314                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19315                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19316                                                    != 0) {
19317                                        clientProcState =
19318                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19319                                    } else {
19320                                        clientProcState =
19321                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19322                                    }
19323                                }
19324                            }
19325                        } else {
19326                            if (clientProcState <
19327                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19328                                clientProcState =
19329                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19330                            }
19331                        }
19332                        if (procState > clientProcState) {
19333                            procState = clientProcState;
19334                        }
19335                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19336                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19337                            app.pendingUiClean = true;
19338                        }
19339                        if (adjType != null) {
19340                            app.adjType = adjType;
19341                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19342                                    .REASON_SERVICE_IN_USE;
19343                            app.adjSource = cr.binding.client;
19344                            app.adjSourceProcState = clientProcState;
19345                            app.adjTarget = s.name;
19346                        }
19347                    }
19348                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19349                        app.treatLikeActivity = true;
19350                    }
19351                    final ActivityRecord a = cr.activity;
19352                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19353                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19354                            (a.visible || a.state == ActivityState.RESUMED ||
19355                             a.state == ActivityState.PAUSING)) {
19356                            adj = ProcessList.FOREGROUND_APP_ADJ;
19357                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19358                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19359                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19360                                } else {
19361                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19362                                }
19363                            }
19364                            app.cached = false;
19365                            app.adjType = "service";
19366                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19367                                    .REASON_SERVICE_IN_USE;
19368                            app.adjSource = a;
19369                            app.adjSourceProcState = procState;
19370                            app.adjTarget = s.name;
19371                        }
19372                    }
19373                }
19374            }
19375        }
19376
19377        for (int provi = app.pubProviders.size()-1;
19378                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19379                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19380                        || procState > ActivityManager.PROCESS_STATE_TOP);
19381                provi--) {
19382            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19383            for (int i = cpr.connections.size()-1;
19384                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19385                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19386                            || procState > ActivityManager.PROCESS_STATE_TOP);
19387                    i--) {
19388                ContentProviderConnection conn = cpr.connections.get(i);
19389                ProcessRecord client = conn.client;
19390                if (client == app) {
19391                    // Being our own client is not interesting.
19392                    continue;
19393                }
19394                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19395                int clientProcState = client.curProcState;
19396                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19397                    // If the other app is cached for any reason, for purposes here
19398                    // we are going to consider it empty.
19399                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19400                }
19401                if (adj > clientAdj) {
19402                    if (app.hasShownUi && app != mHomeProcess
19403                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19404                        app.adjType = "cch-ui-provider";
19405                    } else {
19406                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19407                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19408                        app.adjType = "provider";
19409                    }
19410                    app.cached &= client.cached;
19411                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19412                            .REASON_PROVIDER_IN_USE;
19413                    app.adjSource = client;
19414                    app.adjSourceProcState = clientProcState;
19415                    app.adjTarget = cpr.name;
19416                }
19417                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19418                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19419                        // Special handling of clients who are in the top state.
19420                        // We *may* want to consider this process to be in the
19421                        // top state as well, but only if there is not another
19422                        // reason for it to be running.  Being on the top is a
19423                        // special state, meaning you are specifically running
19424                        // for the current top app.  If the process is already
19425                        // running in the background for some other reason, it
19426                        // is more important to continue considering it to be
19427                        // in the background state.
19428                        mayBeTop = true;
19429                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19430                    } else {
19431                        // Special handling for above-top states (persistent
19432                        // processes).  These should not bring the current process
19433                        // into the top state, since they are not on top.  Instead
19434                        // give them the best state after that.
19435                        clientProcState =
19436                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19437                    }
19438                }
19439                if (procState > clientProcState) {
19440                    procState = clientProcState;
19441                }
19442                if (client.curSchedGroup > schedGroup) {
19443                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19444                }
19445            }
19446            // If the provider has external (non-framework) process
19447            // dependencies, ensure that its adjustment is at least
19448            // FOREGROUND_APP_ADJ.
19449            if (cpr.hasExternalProcessHandles()) {
19450                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19451                    adj = ProcessList.FOREGROUND_APP_ADJ;
19452                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19453                    app.cached = false;
19454                    app.adjType = "provider";
19455                    app.adjTarget = cpr.name;
19456                }
19457                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19458                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19459                }
19460            }
19461        }
19462
19463        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19464            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19465                adj = ProcessList.PREVIOUS_APP_ADJ;
19466                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19467                app.cached = false;
19468                app.adjType = "provider";
19469            }
19470            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19471                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19472            }
19473        }
19474
19475        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19476            // A client of one of our services or providers is in the top state.  We
19477            // *may* want to be in the top state, but not if we are already running in
19478            // the background for some other reason.  For the decision here, we are going
19479            // to pick out a few specific states that we want to remain in when a client
19480            // is top (states that tend to be longer-term) and otherwise allow it to go
19481            // to the top state.
19482            switch (procState) {
19483                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19484                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19485                case ActivityManager.PROCESS_STATE_SERVICE:
19486                    // These all are longer-term states, so pull them up to the top
19487                    // of the background states, but not all the way to the top state.
19488                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19489                    break;
19490                default:
19491                    // Otherwise, top is a better choice, so take it.
19492                    procState = ActivityManager.PROCESS_STATE_TOP;
19493                    break;
19494            }
19495        }
19496
19497        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19498            if (app.hasClientActivities) {
19499                // This is a cached process, but with client activities.  Mark it so.
19500                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19501                app.adjType = "cch-client-act";
19502            } else if (app.treatLikeActivity) {
19503                // This is a cached process, but somebody wants us to treat it like it has
19504                // an activity, okay!
19505                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19506                app.adjType = "cch-as-act";
19507            }
19508        }
19509
19510        if (adj == ProcessList.SERVICE_ADJ) {
19511            if (doingAll) {
19512                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19513                mNewNumServiceProcs++;
19514                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19515                if (!app.serviceb) {
19516                    // This service isn't far enough down on the LRU list to
19517                    // normally be a B service, but if we are low on RAM and it
19518                    // is large we want to force it down since we would prefer to
19519                    // keep launcher over it.
19520                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19521                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19522                        app.serviceHighRam = true;
19523                        app.serviceb = true;
19524                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19525                    } else {
19526                        mNewNumAServiceProcs++;
19527                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19528                    }
19529                } else {
19530                    app.serviceHighRam = false;
19531                }
19532            }
19533            if (app.serviceb) {
19534                adj = ProcessList.SERVICE_B_ADJ;
19535            }
19536        }
19537
19538        app.curRawAdj = adj;
19539
19540        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19541        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19542        if (adj > app.maxAdj) {
19543            adj = app.maxAdj;
19544            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19545                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19546            }
19547        }
19548
19549        // Do final modification to adj.  Everything we do between here and applying
19550        // the final setAdj must be done in this function, because we will also use
19551        // it when computing the final cached adj later.  Note that we don't need to
19552        // worry about this for max adj above, since max adj will always be used to
19553        // keep it out of the cached vaues.
19554        app.curAdj = app.modifyRawOomAdj(adj);
19555        app.curSchedGroup = schedGroup;
19556        app.curProcState = procState;
19557        app.foregroundActivities = foregroundActivities;
19558
19559        return app.curRawAdj;
19560    }
19561
19562    /**
19563     * Record new PSS sample for a process.
19564     */
19565    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19566            long now) {
19567        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19568                swapPss * 1024);
19569        proc.lastPssTime = now;
19570        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19571        if (DEBUG_PSS) Slog.d(TAG_PSS,
19572                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19573                + " state=" + ProcessList.makeProcStateString(procState));
19574        if (proc.initialIdlePss == 0) {
19575            proc.initialIdlePss = pss;
19576        }
19577        proc.lastPss = pss;
19578        proc.lastSwapPss = swapPss;
19579        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19580            proc.lastCachedPss = pss;
19581            proc.lastCachedSwapPss = swapPss;
19582        }
19583
19584        final SparseArray<Pair<Long, String>> watchUids
19585                = mMemWatchProcesses.getMap().get(proc.processName);
19586        Long check = null;
19587        if (watchUids != null) {
19588            Pair<Long, String> val = watchUids.get(proc.uid);
19589            if (val == null) {
19590                val = watchUids.get(0);
19591            }
19592            if (val != null) {
19593                check = val.first;
19594            }
19595        }
19596        if (check != null) {
19597            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19598                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19599                if (!isDebuggable) {
19600                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19601                        isDebuggable = true;
19602                    }
19603                }
19604                if (isDebuggable) {
19605                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19606                    final ProcessRecord myProc = proc;
19607                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19608                    mMemWatchDumpProcName = proc.processName;
19609                    mMemWatchDumpFile = heapdumpFile.toString();
19610                    mMemWatchDumpPid = proc.pid;
19611                    mMemWatchDumpUid = proc.uid;
19612                    BackgroundThread.getHandler().post(new Runnable() {
19613                        @Override
19614                        public void run() {
19615                            revokeUriPermission(ActivityThread.currentActivityThread()
19616                                            .getApplicationThread(),
19617                                    DumpHeapActivity.JAVA_URI,
19618                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19619                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19620                                    UserHandle.myUserId());
19621                            ParcelFileDescriptor fd = null;
19622                            try {
19623                                heapdumpFile.delete();
19624                                fd = ParcelFileDescriptor.open(heapdumpFile,
19625                                        ParcelFileDescriptor.MODE_CREATE |
19626                                                ParcelFileDescriptor.MODE_TRUNCATE |
19627                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19628                                                ParcelFileDescriptor.MODE_APPEND);
19629                                IApplicationThread thread = myProc.thread;
19630                                if (thread != null) {
19631                                    try {
19632                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19633                                                "Requesting dump heap from "
19634                                                + myProc + " to " + heapdumpFile);
19635                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19636                                    } catch (RemoteException e) {
19637                                    }
19638                                }
19639                            } catch (FileNotFoundException e) {
19640                                e.printStackTrace();
19641                            } finally {
19642                                if (fd != null) {
19643                                    try {
19644                                        fd.close();
19645                                    } catch (IOException e) {
19646                                    }
19647                                }
19648                            }
19649                        }
19650                    });
19651                } else {
19652                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19653                            + ", but debugging not enabled");
19654                }
19655            }
19656        }
19657    }
19658
19659    /**
19660     * Schedule PSS collection of a process.
19661     */
19662    void requestPssLocked(ProcessRecord proc, int procState) {
19663        if (mPendingPssProcesses.contains(proc)) {
19664            return;
19665        }
19666        if (mPendingPssProcesses.size() == 0) {
19667            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19668        }
19669        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19670        proc.pssProcState = procState;
19671        mPendingPssProcesses.add(proc);
19672    }
19673
19674    /**
19675     * Schedule PSS collection of all processes.
19676     */
19677    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19678        if (!always) {
19679            if (now < (mLastFullPssTime +
19680                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19681                return;
19682            }
19683        }
19684        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19685        mLastFullPssTime = now;
19686        mFullPssPending = true;
19687        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19688        mPendingPssProcesses.clear();
19689        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19690            ProcessRecord app = mLruProcesses.get(i);
19691            if (app.thread == null
19692                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19693                continue;
19694            }
19695            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19696                app.pssProcState = app.setProcState;
19697                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19698                        mTestPssMode, isSleeping(), now);
19699                mPendingPssProcesses.add(app);
19700            }
19701        }
19702        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19703    }
19704
19705    public void setTestPssMode(boolean enabled) {
19706        synchronized (this) {
19707            mTestPssMode = enabled;
19708            if (enabled) {
19709                // Whenever we enable the mode, we want to take a snapshot all of current
19710                // process mem use.
19711                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19712            }
19713        }
19714    }
19715
19716    /**
19717     * Ask a given process to GC right now.
19718     */
19719    final void performAppGcLocked(ProcessRecord app) {
19720        try {
19721            app.lastRequestedGc = SystemClock.uptimeMillis();
19722            if (app.thread != null) {
19723                if (app.reportLowMemory) {
19724                    app.reportLowMemory = false;
19725                    app.thread.scheduleLowMemory();
19726                } else {
19727                    app.thread.processInBackground();
19728                }
19729            }
19730        } catch (Exception e) {
19731            // whatever.
19732        }
19733    }
19734
19735    /**
19736     * Returns true if things are idle enough to perform GCs.
19737     */
19738    private final boolean canGcNowLocked() {
19739        boolean processingBroadcasts = false;
19740        for (BroadcastQueue q : mBroadcastQueues) {
19741            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19742                processingBroadcasts = true;
19743            }
19744        }
19745        return !processingBroadcasts
19746                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19747    }
19748
19749    /**
19750     * Perform GCs on all processes that are waiting for it, but only
19751     * if things are idle.
19752     */
19753    final void performAppGcsLocked() {
19754        final int N = mProcessesToGc.size();
19755        if (N <= 0) {
19756            return;
19757        }
19758        if (canGcNowLocked()) {
19759            while (mProcessesToGc.size() > 0) {
19760                ProcessRecord proc = mProcessesToGc.remove(0);
19761                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19762                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19763                            <= SystemClock.uptimeMillis()) {
19764                        // To avoid spamming the system, we will GC processes one
19765                        // at a time, waiting a few seconds between each.
19766                        performAppGcLocked(proc);
19767                        scheduleAppGcsLocked();
19768                        return;
19769                    } else {
19770                        // It hasn't been long enough since we last GCed this
19771                        // process...  put it in the list to wait for its time.
19772                        addProcessToGcListLocked(proc);
19773                        break;
19774                    }
19775                }
19776            }
19777
19778            scheduleAppGcsLocked();
19779        }
19780    }
19781
19782    /**
19783     * If all looks good, perform GCs on all processes waiting for them.
19784     */
19785    final void performAppGcsIfAppropriateLocked() {
19786        if (canGcNowLocked()) {
19787            performAppGcsLocked();
19788            return;
19789        }
19790        // Still not idle, wait some more.
19791        scheduleAppGcsLocked();
19792    }
19793
19794    /**
19795     * Schedule the execution of all pending app GCs.
19796     */
19797    final void scheduleAppGcsLocked() {
19798        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19799
19800        if (mProcessesToGc.size() > 0) {
19801            // Schedule a GC for the time to the next process.
19802            ProcessRecord proc = mProcessesToGc.get(0);
19803            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19804
19805            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19806            long now = SystemClock.uptimeMillis();
19807            if (when < (now+GC_TIMEOUT)) {
19808                when = now + GC_TIMEOUT;
19809            }
19810            mHandler.sendMessageAtTime(msg, when);
19811        }
19812    }
19813
19814    /**
19815     * Add a process to the array of processes waiting to be GCed.  Keeps the
19816     * list in sorted order by the last GC time.  The process can't already be
19817     * on the list.
19818     */
19819    final void addProcessToGcListLocked(ProcessRecord proc) {
19820        boolean added = false;
19821        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19822            if (mProcessesToGc.get(i).lastRequestedGc <
19823                    proc.lastRequestedGc) {
19824                added = true;
19825                mProcessesToGc.add(i+1, proc);
19826                break;
19827            }
19828        }
19829        if (!added) {
19830            mProcessesToGc.add(0, proc);
19831        }
19832    }
19833
19834    /**
19835     * Set up to ask a process to GC itself.  This will either do it
19836     * immediately, or put it on the list of processes to gc the next
19837     * time things are idle.
19838     */
19839    final void scheduleAppGcLocked(ProcessRecord app) {
19840        long now = SystemClock.uptimeMillis();
19841        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19842            return;
19843        }
19844        if (!mProcessesToGc.contains(app)) {
19845            addProcessToGcListLocked(app);
19846            scheduleAppGcsLocked();
19847        }
19848    }
19849
19850    final void checkExcessivePowerUsageLocked(boolean doKills) {
19851        updateCpuStatsNow();
19852
19853        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19854        boolean doWakeKills = doKills;
19855        boolean doCpuKills = doKills;
19856        if (mLastPowerCheckRealtime == 0) {
19857            doWakeKills = false;
19858        }
19859        if (mLastPowerCheckUptime == 0) {
19860            doCpuKills = false;
19861        }
19862        if (stats.isScreenOn()) {
19863            doWakeKills = false;
19864        }
19865        final long curRealtime = SystemClock.elapsedRealtime();
19866        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19867        final long curUptime = SystemClock.uptimeMillis();
19868        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19869        mLastPowerCheckRealtime = curRealtime;
19870        mLastPowerCheckUptime = curUptime;
19871        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19872            doWakeKills = false;
19873        }
19874        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19875            doCpuKills = false;
19876        }
19877        int i = mLruProcesses.size();
19878        while (i > 0) {
19879            i--;
19880            ProcessRecord app = mLruProcesses.get(i);
19881            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19882                long wtime;
19883                synchronized (stats) {
19884                    wtime = stats.getProcessWakeTime(app.info.uid,
19885                            app.pid, curRealtime);
19886                }
19887                long wtimeUsed = wtime - app.lastWakeTime;
19888                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19889                if (DEBUG_POWER) {
19890                    StringBuilder sb = new StringBuilder(128);
19891                    sb.append("Wake for ");
19892                    app.toShortString(sb);
19893                    sb.append(": over ");
19894                    TimeUtils.formatDuration(realtimeSince, sb);
19895                    sb.append(" used ");
19896                    TimeUtils.formatDuration(wtimeUsed, sb);
19897                    sb.append(" (");
19898                    sb.append((wtimeUsed*100)/realtimeSince);
19899                    sb.append("%)");
19900                    Slog.i(TAG_POWER, sb.toString());
19901                    sb.setLength(0);
19902                    sb.append("CPU for ");
19903                    app.toShortString(sb);
19904                    sb.append(": over ");
19905                    TimeUtils.formatDuration(uptimeSince, sb);
19906                    sb.append(" used ");
19907                    TimeUtils.formatDuration(cputimeUsed, sb);
19908                    sb.append(" (");
19909                    sb.append((cputimeUsed*100)/uptimeSince);
19910                    sb.append("%)");
19911                    Slog.i(TAG_POWER, sb.toString());
19912                }
19913                // If a process has held a wake lock for more
19914                // than 50% of the time during this period,
19915                // that sounds bad.  Kill!
19916                if (doWakeKills && realtimeSince > 0
19917                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19918                    synchronized (stats) {
19919                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19920                                realtimeSince, wtimeUsed);
19921                    }
19922                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19923                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19924                } else if (doCpuKills && uptimeSince > 0
19925                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19926                    synchronized (stats) {
19927                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19928                                uptimeSince, cputimeUsed);
19929                    }
19930                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19931                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19932                } else {
19933                    app.lastWakeTime = wtime;
19934                    app.lastCpuTime = app.curCpuTime;
19935                }
19936            }
19937        }
19938    }
19939
19940    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19941            long nowElapsed) {
19942        boolean success = true;
19943
19944        if (app.curRawAdj != app.setRawAdj) {
19945            app.setRawAdj = app.curRawAdj;
19946        }
19947
19948        int changes = 0;
19949
19950        if (app.curAdj != app.setAdj) {
19951            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19952            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19953                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19954                    + app.adjType);
19955            app.setAdj = app.curAdj;
19956        }
19957
19958        if (app.setSchedGroup != app.curSchedGroup) {
19959            app.setSchedGroup = app.curSchedGroup;
19960            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19961                    "Setting sched group of " + app.processName
19962                    + " to " + app.curSchedGroup);
19963            if (app.waitingToKill != null && app.curReceiver == null
19964                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19965                app.kill(app.waitingToKill, true);
19966                success = false;
19967            } else {
19968                int processGroup;
19969                switch (app.curSchedGroup) {
19970                    case ProcessList.SCHED_GROUP_BACKGROUND:
19971                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19972                        break;
19973                    case ProcessList.SCHED_GROUP_TOP_APP:
19974                        processGroup = Process.THREAD_GROUP_TOP_APP;
19975                        break;
19976                    default:
19977                        processGroup = Process.THREAD_GROUP_DEFAULT;
19978                        break;
19979                }
19980                if (true) {
19981                    long oldId = Binder.clearCallingIdentity();
19982                    try {
19983                        Process.setProcessGroup(app.pid, processGroup);
19984                    } catch (Exception e) {
19985                        Slog.w(TAG, "Failed setting process group of " + app.pid
19986                                + " to " + app.curSchedGroup);
19987                        e.printStackTrace();
19988                    } finally {
19989                        Binder.restoreCallingIdentity(oldId);
19990                    }
19991                } else {
19992                    if (app.thread != null) {
19993                        try {
19994                            app.thread.setSchedulingGroup(processGroup);
19995                        } catch (RemoteException e) {
19996                        }
19997                    }
19998                }
19999            }
20000        }
20001        if (app.repForegroundActivities != app.foregroundActivities) {
20002            app.repForegroundActivities = app.foregroundActivities;
20003            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20004        }
20005        if (app.repProcState != app.curProcState) {
20006            app.repProcState = app.curProcState;
20007            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20008            if (app.thread != null) {
20009                try {
20010                    if (false) {
20011                        //RuntimeException h = new RuntimeException("here");
20012                        Slog.i(TAG, "Sending new process state " + app.repProcState
20013                                + " to " + app /*, h*/);
20014                    }
20015                    app.thread.setProcessState(app.repProcState);
20016                } catch (RemoteException e) {
20017                }
20018            }
20019        }
20020        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20021                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20022            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20023                // Experimental code to more aggressively collect pss while
20024                // running test...  the problem is that this tends to collect
20025                // the data right when a process is transitioning between process
20026                // states, which well tend to give noisy data.
20027                long start = SystemClock.uptimeMillis();
20028                long pss = Debug.getPss(app.pid, mTmpLong, null);
20029                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20030                mPendingPssProcesses.remove(app);
20031                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20032                        + " to " + app.curProcState + ": "
20033                        + (SystemClock.uptimeMillis()-start) + "ms");
20034            }
20035            app.lastStateTime = now;
20036            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20037                    mTestPssMode, isSleeping(), now);
20038            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20039                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20040                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20041                    + (app.nextPssTime-now) + ": " + app);
20042        } else {
20043            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20044                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20045                    mTestPssMode)))) {
20046                requestPssLocked(app, app.setProcState);
20047                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20048                        mTestPssMode, isSleeping(), now);
20049            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20050                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20051        }
20052        if (app.setProcState != app.curProcState) {
20053            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20054                    "Proc state change of " + app.processName
20055                            + " to " + app.curProcState);
20056            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20057            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20058            if (setImportant && !curImportant) {
20059                // This app is no longer something we consider important enough to allow to
20060                // use arbitrary amounts of battery power.  Note
20061                // its current wake lock time to later know to kill it if
20062                // it is not behaving well.
20063                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20064                synchronized (stats) {
20065                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20066                            app.pid, nowElapsed);
20067                }
20068                app.lastCpuTime = app.curCpuTime;
20069
20070            }
20071            // Inform UsageStats of important process state change
20072            // Must be called before updating setProcState
20073            maybeUpdateUsageStatsLocked(app, nowElapsed);
20074
20075            app.setProcState = app.curProcState;
20076            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20077                app.notCachedSinceIdle = false;
20078            }
20079            if (!doingAll) {
20080                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20081            } else {
20082                app.procStateChanged = true;
20083            }
20084        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20085                > USAGE_STATS_INTERACTION_INTERVAL) {
20086            // For apps that sit around for a long time in the interactive state, we need
20087            // to report this at least once a day so they don't go idle.
20088            maybeUpdateUsageStatsLocked(app, nowElapsed);
20089        }
20090
20091        if (changes != 0) {
20092            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20093                    "Changes in " + app + ": " + changes);
20094            int i = mPendingProcessChanges.size()-1;
20095            ProcessChangeItem item = null;
20096            while (i >= 0) {
20097                item = mPendingProcessChanges.get(i);
20098                if (item.pid == app.pid) {
20099                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20100                            "Re-using existing item: " + item);
20101                    break;
20102                }
20103                i--;
20104            }
20105            if (i < 0) {
20106                // No existing item in pending changes; need a new one.
20107                final int NA = mAvailProcessChanges.size();
20108                if (NA > 0) {
20109                    item = mAvailProcessChanges.remove(NA-1);
20110                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20111                            "Retrieving available item: " + item);
20112                } else {
20113                    item = new ProcessChangeItem();
20114                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20115                            "Allocating new item: " + item);
20116                }
20117                item.changes = 0;
20118                item.pid = app.pid;
20119                item.uid = app.info.uid;
20120                if (mPendingProcessChanges.size() == 0) {
20121                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20122                            "*** Enqueueing dispatch processes changed!");
20123                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20124                }
20125                mPendingProcessChanges.add(item);
20126            }
20127            item.changes |= changes;
20128            item.processState = app.repProcState;
20129            item.foregroundActivities = app.repForegroundActivities;
20130            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20131                    "Item " + Integer.toHexString(System.identityHashCode(item))
20132                    + " " + app.toShortString() + ": changes=" + item.changes
20133                    + " procState=" + item.processState
20134                    + " foreground=" + item.foregroundActivities
20135                    + " type=" + app.adjType + " source=" + app.adjSource
20136                    + " target=" + app.adjTarget);
20137        }
20138
20139        return success;
20140    }
20141
20142    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20143        final UidRecord.ChangeItem pendingChange;
20144        if (uidRec == null || uidRec.pendingChange == null) {
20145            if (mPendingUidChanges.size() == 0) {
20146                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20147                        "*** Enqueueing dispatch uid changed!");
20148                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20149            }
20150            final int NA = mAvailUidChanges.size();
20151            if (NA > 0) {
20152                pendingChange = mAvailUidChanges.remove(NA-1);
20153                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20154                        "Retrieving available item: " + pendingChange);
20155            } else {
20156                pendingChange = new UidRecord.ChangeItem();
20157                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20158                        "Allocating new item: " + pendingChange);
20159            }
20160            if (uidRec != null) {
20161                uidRec.pendingChange = pendingChange;
20162                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20163                    // If this uid is going away, and we haven't yet reported it is gone,
20164                    // then do so now.
20165                    change = UidRecord.CHANGE_GONE_IDLE;
20166                }
20167            } else if (uid < 0) {
20168                throw new IllegalArgumentException("No UidRecord or uid");
20169            }
20170            pendingChange.uidRecord = uidRec;
20171            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20172            mPendingUidChanges.add(pendingChange);
20173        } else {
20174            pendingChange = uidRec.pendingChange;
20175            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20176                change = UidRecord.CHANGE_GONE_IDLE;
20177            }
20178        }
20179        pendingChange.change = change;
20180        pendingChange.processState = uidRec != null
20181                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20182    }
20183
20184    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20185            String authority) {
20186        if (app == null) return;
20187        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20188            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20189            if (userState == null) return;
20190            final long now = SystemClock.elapsedRealtime();
20191            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20192            if (lastReported == null || lastReported < now - 60 * 1000L) {
20193                mUsageStatsService.reportContentProviderUsage(
20194                        authority, providerPkgName, app.userId);
20195                userState.mProviderLastReportedFg.put(authority, now);
20196            }
20197        }
20198    }
20199
20200    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20201        if (DEBUG_USAGE_STATS) {
20202            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20203                    + "] state changes: old = " + app.setProcState + ", new = "
20204                    + app.curProcState);
20205        }
20206        if (mUsageStatsService == null) {
20207            return;
20208        }
20209        boolean isInteraction;
20210        // To avoid some abuse patterns, we are going to be careful about what we consider
20211        // to be an app interaction.  Being the top activity doesn't count while the display
20212        // is sleeping, nor do short foreground services.
20213        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20214            isInteraction = true;
20215            app.fgInteractionTime = 0;
20216        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20217            if (app.fgInteractionTime == 0) {
20218                app.fgInteractionTime = nowElapsed;
20219                isInteraction = false;
20220            } else {
20221                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20222            }
20223        } else {
20224            isInteraction = app.curProcState
20225                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20226            app.fgInteractionTime = 0;
20227        }
20228        if (isInteraction && (!app.reportedInteraction
20229                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20230            app.interactionEventTime = nowElapsed;
20231            String[] packages = app.getPackageList();
20232            if (packages != null) {
20233                for (int i = 0; i < packages.length; i++) {
20234                    mUsageStatsService.reportEvent(packages[i], app.userId,
20235                            UsageEvents.Event.SYSTEM_INTERACTION);
20236                }
20237            }
20238        }
20239        app.reportedInteraction = isInteraction;
20240        if (!isInteraction) {
20241            app.interactionEventTime = 0;
20242        }
20243    }
20244
20245    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20246        if (proc.thread != null) {
20247            if (proc.baseProcessTracker != null) {
20248                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20249            }
20250        }
20251    }
20252
20253    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20254            ProcessRecord TOP_APP, boolean doingAll, long now) {
20255        if (app.thread == null) {
20256            return false;
20257        }
20258
20259        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20260
20261        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20262    }
20263
20264    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20265            boolean oomAdj) {
20266        if (isForeground != proc.foregroundServices) {
20267            proc.foregroundServices = isForeground;
20268            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20269                    proc.info.uid);
20270            if (isForeground) {
20271                if (curProcs == null) {
20272                    curProcs = new ArrayList<ProcessRecord>();
20273                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20274                }
20275                if (!curProcs.contains(proc)) {
20276                    curProcs.add(proc);
20277                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20278                            proc.info.packageName, proc.info.uid);
20279                }
20280            } else {
20281                if (curProcs != null) {
20282                    if (curProcs.remove(proc)) {
20283                        mBatteryStatsService.noteEvent(
20284                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20285                                proc.info.packageName, proc.info.uid);
20286                        if (curProcs.size() <= 0) {
20287                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20288                        }
20289                    }
20290                }
20291            }
20292            if (oomAdj) {
20293                updateOomAdjLocked();
20294            }
20295        }
20296    }
20297
20298    private final ActivityRecord resumedAppLocked() {
20299        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20300        String pkg;
20301        int uid;
20302        if (act != null) {
20303            pkg = act.packageName;
20304            uid = act.info.applicationInfo.uid;
20305        } else {
20306            pkg = null;
20307            uid = -1;
20308        }
20309        // Has the UID or resumed package name changed?
20310        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20311                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20312            if (mCurResumedPackage != null) {
20313                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20314                        mCurResumedPackage, mCurResumedUid);
20315            }
20316            mCurResumedPackage = pkg;
20317            mCurResumedUid = uid;
20318            if (mCurResumedPackage != null) {
20319                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20320                        mCurResumedPackage, mCurResumedUid);
20321            }
20322        }
20323        return act;
20324    }
20325
20326    final boolean updateOomAdjLocked(ProcessRecord app) {
20327        final ActivityRecord TOP_ACT = resumedAppLocked();
20328        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20329        final boolean wasCached = app.cached;
20330
20331        mAdjSeq++;
20332
20333        // This is the desired cached adjusment we want to tell it to use.
20334        // If our app is currently cached, we know it, and that is it.  Otherwise,
20335        // we don't know it yet, and it needs to now be cached we will then
20336        // need to do a complete oom adj.
20337        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20338                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20339        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20340                SystemClock.uptimeMillis());
20341        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20342            // Changed to/from cached state, so apps after it in the LRU
20343            // list may also be changed.
20344            updateOomAdjLocked();
20345        }
20346        return success;
20347    }
20348
20349    final void updateOomAdjLocked() {
20350        final ActivityRecord TOP_ACT = resumedAppLocked();
20351        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20352        final long now = SystemClock.uptimeMillis();
20353        final long nowElapsed = SystemClock.elapsedRealtime();
20354        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20355        final int N = mLruProcesses.size();
20356
20357        if (false) {
20358            RuntimeException e = new RuntimeException();
20359            e.fillInStackTrace();
20360            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20361        }
20362
20363        // Reset state in all uid records.
20364        for (int i=mActiveUids.size()-1; i>=0; i--) {
20365            final UidRecord uidRec = mActiveUids.valueAt(i);
20366            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20367                    "Starting update of " + uidRec);
20368            uidRec.reset();
20369        }
20370
20371        mStackSupervisor.rankTaskLayersIfNeeded();
20372
20373        mAdjSeq++;
20374        mNewNumServiceProcs = 0;
20375        mNewNumAServiceProcs = 0;
20376
20377        final int emptyProcessLimit;
20378        final int cachedProcessLimit;
20379        if (mProcessLimit <= 0) {
20380            emptyProcessLimit = cachedProcessLimit = 0;
20381        } else if (mProcessLimit == 1) {
20382            emptyProcessLimit = 1;
20383            cachedProcessLimit = 0;
20384        } else {
20385            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20386            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20387        }
20388
20389        // Let's determine how many processes we have running vs.
20390        // how many slots we have for background processes; we may want
20391        // to put multiple processes in a slot of there are enough of
20392        // them.
20393        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20394                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20395        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20396        if (numEmptyProcs > cachedProcessLimit) {
20397            // If there are more empty processes than our limit on cached
20398            // processes, then use the cached process limit for the factor.
20399            // This ensures that the really old empty processes get pushed
20400            // down to the bottom, so if we are running low on memory we will
20401            // have a better chance at keeping around more cached processes
20402            // instead of a gazillion empty processes.
20403            numEmptyProcs = cachedProcessLimit;
20404        }
20405        int emptyFactor = numEmptyProcs/numSlots;
20406        if (emptyFactor < 1) emptyFactor = 1;
20407        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20408        if (cachedFactor < 1) cachedFactor = 1;
20409        int stepCached = 0;
20410        int stepEmpty = 0;
20411        int numCached = 0;
20412        int numEmpty = 0;
20413        int numTrimming = 0;
20414
20415        mNumNonCachedProcs = 0;
20416        mNumCachedHiddenProcs = 0;
20417
20418        // First update the OOM adjustment for each of the
20419        // application processes based on their current state.
20420        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20421        int nextCachedAdj = curCachedAdj+1;
20422        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20423        int nextEmptyAdj = curEmptyAdj+2;
20424        for (int i=N-1; i>=0; i--) {
20425            ProcessRecord app = mLruProcesses.get(i);
20426            if (!app.killedByAm && app.thread != null) {
20427                app.procStateChanged = false;
20428                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20429
20430                // If we haven't yet assigned the final cached adj
20431                // to the process, do that now.
20432                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20433                    switch (app.curProcState) {
20434                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20435                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20436                            // This process is a cached process holding activities...
20437                            // assign it the next cached value for that type, and then
20438                            // step that cached level.
20439                            app.curRawAdj = curCachedAdj;
20440                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20441                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20442                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20443                                    + ")");
20444                            if (curCachedAdj != nextCachedAdj) {
20445                                stepCached++;
20446                                if (stepCached >= cachedFactor) {
20447                                    stepCached = 0;
20448                                    curCachedAdj = nextCachedAdj;
20449                                    nextCachedAdj += 2;
20450                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20451                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20452                                    }
20453                                }
20454                            }
20455                            break;
20456                        default:
20457                            // For everything else, assign next empty cached process
20458                            // level and bump that up.  Note that this means that
20459                            // long-running services that have dropped down to the
20460                            // cached level will be treated as empty (since their process
20461                            // state is still as a service), which is what we want.
20462                            app.curRawAdj = curEmptyAdj;
20463                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20464                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20465                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20466                                    + ")");
20467                            if (curEmptyAdj != nextEmptyAdj) {
20468                                stepEmpty++;
20469                                if (stepEmpty >= emptyFactor) {
20470                                    stepEmpty = 0;
20471                                    curEmptyAdj = nextEmptyAdj;
20472                                    nextEmptyAdj += 2;
20473                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20474                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20475                                    }
20476                                }
20477                            }
20478                            break;
20479                    }
20480                }
20481
20482                applyOomAdjLocked(app, true, now, nowElapsed);
20483
20484                // Count the number of process types.
20485                switch (app.curProcState) {
20486                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20487                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20488                        mNumCachedHiddenProcs++;
20489                        numCached++;
20490                        if (numCached > cachedProcessLimit) {
20491                            app.kill("cached #" + numCached, true);
20492                        }
20493                        break;
20494                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20495                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20496                                && app.lastActivityTime < oldTime) {
20497                            app.kill("empty for "
20498                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20499                                    / 1000) + "s", true);
20500                        } else {
20501                            numEmpty++;
20502                            if (numEmpty > emptyProcessLimit) {
20503                                app.kill("empty #" + numEmpty, true);
20504                            }
20505                        }
20506                        break;
20507                    default:
20508                        mNumNonCachedProcs++;
20509                        break;
20510                }
20511
20512                if (app.isolated && app.services.size() <= 0) {
20513                    // If this is an isolated process, and there are no
20514                    // services running in it, then the process is no longer
20515                    // needed.  We agressively kill these because we can by
20516                    // definition not re-use the same process again, and it is
20517                    // good to avoid having whatever code was running in them
20518                    // left sitting around after no longer needed.
20519                    app.kill("isolated not needed", true);
20520                } else {
20521                    // Keeping this process, update its uid.
20522                    final UidRecord uidRec = app.uidRecord;
20523                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20524                        uidRec.curProcState = app.curProcState;
20525                    }
20526                }
20527
20528                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20529                        && !app.killedByAm) {
20530                    numTrimming++;
20531                }
20532            }
20533        }
20534
20535        mNumServiceProcs = mNewNumServiceProcs;
20536
20537        // Now determine the memory trimming level of background processes.
20538        // Unfortunately we need to start at the back of the list to do this
20539        // properly.  We only do this if the number of background apps we
20540        // are managing to keep around is less than half the maximum we desire;
20541        // if we are keeping a good number around, we'll let them use whatever
20542        // memory they want.
20543        final int numCachedAndEmpty = numCached + numEmpty;
20544        int memFactor;
20545        if (numCached <= ProcessList.TRIM_CACHED_APPS
20546                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20547            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20548                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20549            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20550                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20551            } else {
20552                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20553            }
20554        } else {
20555            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20556        }
20557        // We always allow the memory level to go up (better).  We only allow it to go
20558        // down if we are in a state where that is allowed, *and* the total number of processes
20559        // has gone down since last time.
20560        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20561                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20562                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20563        if (memFactor > mLastMemoryLevel) {
20564            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20565                memFactor = mLastMemoryLevel;
20566                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20567            }
20568        }
20569        if (memFactor != mLastMemoryLevel) {
20570            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20571        }
20572        mLastMemoryLevel = memFactor;
20573        mLastNumProcesses = mLruProcesses.size();
20574        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20575        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20576        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20577            if (mLowRamStartTime == 0) {
20578                mLowRamStartTime = now;
20579            }
20580            int step = 0;
20581            int fgTrimLevel;
20582            switch (memFactor) {
20583                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20584                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20585                    break;
20586                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20587                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20588                    break;
20589                default:
20590                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20591                    break;
20592            }
20593            int factor = numTrimming/3;
20594            int minFactor = 2;
20595            if (mHomeProcess != null) minFactor++;
20596            if (mPreviousProcess != null) minFactor++;
20597            if (factor < minFactor) factor = minFactor;
20598            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20599            for (int i=N-1; i>=0; i--) {
20600                ProcessRecord app = mLruProcesses.get(i);
20601                if (allChanged || app.procStateChanged) {
20602                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20603                    app.procStateChanged = false;
20604                }
20605                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20606                        && !app.killedByAm) {
20607                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20608                        try {
20609                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20610                                    "Trimming memory of " + app.processName + " to " + curLevel);
20611                            app.thread.scheduleTrimMemory(curLevel);
20612                        } catch (RemoteException e) {
20613                        }
20614                        if (false) {
20615                            // For now we won't do this; our memory trimming seems
20616                            // to be good enough at this point that destroying
20617                            // activities causes more harm than good.
20618                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20619                                    && app != mHomeProcess && app != mPreviousProcess) {
20620                                // Need to do this on its own message because the stack may not
20621                                // be in a consistent state at this point.
20622                                // For these apps we will also finish their activities
20623                                // to help them free memory.
20624                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20625                            }
20626                        }
20627                    }
20628                    app.trimMemoryLevel = curLevel;
20629                    step++;
20630                    if (step >= factor) {
20631                        step = 0;
20632                        switch (curLevel) {
20633                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20634                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20635                                break;
20636                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20637                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20638                                break;
20639                        }
20640                    }
20641                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20642                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20643                            && app.thread != null) {
20644                        try {
20645                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20646                                    "Trimming memory of heavy-weight " + app.processName
20647                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20648                            app.thread.scheduleTrimMemory(
20649                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20650                        } catch (RemoteException e) {
20651                        }
20652                    }
20653                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20654                } else {
20655                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20656                            || app.systemNoUi) && app.pendingUiClean) {
20657                        // If this application is now in the background and it
20658                        // had done UI, then give it the special trim level to
20659                        // have it free UI resources.
20660                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20661                        if (app.trimMemoryLevel < level && app.thread != null) {
20662                            try {
20663                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20664                                        "Trimming memory of bg-ui " + app.processName
20665                                        + " to " + level);
20666                                app.thread.scheduleTrimMemory(level);
20667                            } catch (RemoteException e) {
20668                            }
20669                        }
20670                        app.pendingUiClean = false;
20671                    }
20672                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20673                        try {
20674                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20675                                    "Trimming memory of fg " + app.processName
20676                                    + " to " + fgTrimLevel);
20677                            app.thread.scheduleTrimMemory(fgTrimLevel);
20678                        } catch (RemoteException e) {
20679                        }
20680                    }
20681                    app.trimMemoryLevel = fgTrimLevel;
20682                }
20683            }
20684        } else {
20685            if (mLowRamStartTime != 0) {
20686                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20687                mLowRamStartTime = 0;
20688            }
20689            for (int i=N-1; i>=0; i--) {
20690                ProcessRecord app = mLruProcesses.get(i);
20691                if (allChanged || app.procStateChanged) {
20692                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20693                    app.procStateChanged = false;
20694                }
20695                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20696                        || app.systemNoUi) && app.pendingUiClean) {
20697                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20698                            && app.thread != null) {
20699                        try {
20700                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20701                                    "Trimming memory of ui hidden " + app.processName
20702                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20703                            app.thread.scheduleTrimMemory(
20704                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20705                        } catch (RemoteException e) {
20706                        }
20707                    }
20708                    app.pendingUiClean = false;
20709                }
20710                app.trimMemoryLevel = 0;
20711            }
20712        }
20713
20714        if (mAlwaysFinishActivities) {
20715            // Need to do this on its own message because the stack may not
20716            // be in a consistent state at this point.
20717            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20718        }
20719
20720        if (allChanged) {
20721            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20722        }
20723
20724        // Update from any uid changes.
20725        for (int i=mActiveUids.size()-1; i>=0; i--) {
20726            final UidRecord uidRec = mActiveUids.valueAt(i);
20727            int uidChange = UidRecord.CHANGE_PROCSTATE;
20728            if (uidRec.setProcState != uidRec.curProcState) {
20729                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20730                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20731                        + " to " + uidRec.curProcState);
20732                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20733                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20734                        uidRec.lastBackgroundTime = nowElapsed;
20735                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20736                            // Note: the background settle time is in elapsed realtime, while
20737                            // the handler time base is uptime.  All this means is that we may
20738                            // stop background uids later than we had intended, but that only
20739                            // happens because the device was sleeping so we are okay anyway.
20740                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20741                        }
20742                    }
20743                } else {
20744                    if (uidRec.idle) {
20745                        uidChange = UidRecord.CHANGE_ACTIVE;
20746                        uidRec.idle = false;
20747                    }
20748                    uidRec.lastBackgroundTime = 0;
20749                }
20750                uidRec.setProcState = uidRec.curProcState;
20751                enqueueUidChangeLocked(uidRec, -1, uidChange);
20752                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20753            }
20754        }
20755
20756        if (mProcessStats.shouldWriteNowLocked(now)) {
20757            mHandler.post(new Runnable() {
20758                @Override public void run() {
20759                    synchronized (ActivityManagerService.this) {
20760                        mProcessStats.writeStateAsyncLocked();
20761                    }
20762                }
20763            });
20764        }
20765
20766        if (DEBUG_OOM_ADJ) {
20767            final long duration = SystemClock.uptimeMillis() - now;
20768            if (false) {
20769                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20770                        new RuntimeException("here").fillInStackTrace());
20771            } else {
20772                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20773            }
20774        }
20775    }
20776
20777    final void idleUids() {
20778        synchronized (this) {
20779            final long nowElapsed = SystemClock.elapsedRealtime();
20780            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20781            long nextTime = 0;
20782            for (int i=mActiveUids.size()-1; i>=0; i--) {
20783                final UidRecord uidRec = mActiveUids.valueAt(i);
20784                final long bgTime = uidRec.lastBackgroundTime;
20785                if (bgTime > 0 && !uidRec.idle) {
20786                    if (bgTime <= maxBgTime) {
20787                        uidRec.idle = true;
20788                        doStopUidLocked(uidRec.uid, uidRec);
20789                    } else {
20790                        if (nextTime == 0 || nextTime > bgTime) {
20791                            nextTime = bgTime;
20792                        }
20793                    }
20794                }
20795            }
20796            if (nextTime > 0) {
20797                mHandler.removeMessages(IDLE_UIDS_MSG);
20798                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20799                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20800            }
20801        }
20802    }
20803
20804    final void runInBackgroundDisabled(int uid) {
20805        synchronized (this) {
20806            UidRecord uidRec = mActiveUids.get(uid);
20807            if (uidRec != null) {
20808                // This uid is actually running...  should it be considered background now?
20809                if (uidRec.idle) {
20810                    doStopUidLocked(uidRec.uid, uidRec);
20811                }
20812            } else {
20813                // This uid isn't actually running...  still send a report about it being "stopped".
20814                doStopUidLocked(uid, null);
20815            }
20816        }
20817    }
20818
20819    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20820        mServices.stopInBackgroundLocked(uid);
20821        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20822    }
20823
20824    final void trimApplications() {
20825        synchronized (this) {
20826            int i;
20827
20828            // First remove any unused application processes whose package
20829            // has been removed.
20830            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20831                final ProcessRecord app = mRemovedProcesses.get(i);
20832                if (app.activities.size() == 0
20833                        && app.curReceiver == null && app.services.size() == 0) {
20834                    Slog.i(
20835                        TAG, "Exiting empty application process "
20836                        + app.toShortString() + " ("
20837                        + (app.thread != null ? app.thread.asBinder() : null)
20838                        + ")\n");
20839                    if (app.pid > 0 && app.pid != MY_PID) {
20840                        app.kill("empty", false);
20841                    } else {
20842                        try {
20843                            app.thread.scheduleExit();
20844                        } catch (Exception e) {
20845                            // Ignore exceptions.
20846                        }
20847                    }
20848                    cleanUpApplicationRecordLocked(app, false, true, -1);
20849                    mRemovedProcesses.remove(i);
20850
20851                    if (app.persistent) {
20852                        addAppLocked(app.info, false, null /* ABI override */);
20853                    }
20854                }
20855            }
20856
20857            // Now update the oom adj for all processes.
20858            updateOomAdjLocked();
20859        }
20860    }
20861
20862    /** This method sends the specified signal to each of the persistent apps */
20863    public void signalPersistentProcesses(int sig) throws RemoteException {
20864        if (sig != Process.SIGNAL_USR1) {
20865            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20866        }
20867
20868        synchronized (this) {
20869            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20870                    != PackageManager.PERMISSION_GRANTED) {
20871                throw new SecurityException("Requires permission "
20872                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20873            }
20874
20875            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20876                ProcessRecord r = mLruProcesses.get(i);
20877                if (r.thread != null && r.persistent) {
20878                    Process.sendSignal(r.pid, sig);
20879                }
20880            }
20881        }
20882    }
20883
20884    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20885        if (proc == null || proc == mProfileProc) {
20886            proc = mProfileProc;
20887            profileType = mProfileType;
20888            clearProfilerLocked();
20889        }
20890        if (proc == null) {
20891            return;
20892        }
20893        try {
20894            proc.thread.profilerControl(false, null, profileType);
20895        } catch (RemoteException e) {
20896            throw new IllegalStateException("Process disappeared");
20897        }
20898    }
20899
20900    private void clearProfilerLocked() {
20901        if (mProfileFd != null) {
20902            try {
20903                mProfileFd.close();
20904            } catch (IOException e) {
20905            }
20906        }
20907        mProfileApp = null;
20908        mProfileProc = null;
20909        mProfileFile = null;
20910        mProfileType = 0;
20911        mAutoStopProfiler = false;
20912        mSamplingInterval = 0;
20913    }
20914
20915    public boolean profileControl(String process, int userId, boolean start,
20916            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20917
20918        try {
20919            synchronized (this) {
20920                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20921                // its own permission.
20922                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20923                        != PackageManager.PERMISSION_GRANTED) {
20924                    throw new SecurityException("Requires permission "
20925                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20926                }
20927
20928                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20929                    throw new IllegalArgumentException("null profile info or fd");
20930                }
20931
20932                ProcessRecord proc = null;
20933                if (process != null) {
20934                    proc = findProcessLocked(process, userId, "profileControl");
20935                }
20936
20937                if (start && (proc == null || proc.thread == null)) {
20938                    throw new IllegalArgumentException("Unknown process: " + process);
20939                }
20940
20941                if (start) {
20942                    stopProfilerLocked(null, 0);
20943                    setProfileApp(proc.info, proc.processName, profilerInfo);
20944                    mProfileProc = proc;
20945                    mProfileType = profileType;
20946                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20947                    try {
20948                        fd = fd.dup();
20949                    } catch (IOException e) {
20950                        fd = null;
20951                    }
20952                    profilerInfo.profileFd = fd;
20953                    proc.thread.profilerControl(start, profilerInfo, profileType);
20954                    fd = null;
20955                    mProfileFd = null;
20956                } else {
20957                    stopProfilerLocked(proc, profileType);
20958                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20959                        try {
20960                            profilerInfo.profileFd.close();
20961                        } catch (IOException e) {
20962                        }
20963                    }
20964                }
20965
20966                return true;
20967            }
20968        } catch (RemoteException e) {
20969            throw new IllegalStateException("Process disappeared");
20970        } finally {
20971            if (profilerInfo != null && profilerInfo.profileFd != null) {
20972                try {
20973                    profilerInfo.profileFd.close();
20974                } catch (IOException e) {
20975                }
20976            }
20977        }
20978    }
20979
20980    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20981        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20982                userId, true, ALLOW_FULL_ONLY, callName, null);
20983        ProcessRecord proc = null;
20984        try {
20985            int pid = Integer.parseInt(process);
20986            synchronized (mPidsSelfLocked) {
20987                proc = mPidsSelfLocked.get(pid);
20988            }
20989        } catch (NumberFormatException e) {
20990        }
20991
20992        if (proc == null) {
20993            ArrayMap<String, SparseArray<ProcessRecord>> all
20994                    = mProcessNames.getMap();
20995            SparseArray<ProcessRecord> procs = all.get(process);
20996            if (procs != null && procs.size() > 0) {
20997                proc = procs.valueAt(0);
20998                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20999                    for (int i=1; i<procs.size(); i++) {
21000                        ProcessRecord thisProc = procs.valueAt(i);
21001                        if (thisProc.userId == userId) {
21002                            proc = thisProc;
21003                            break;
21004                        }
21005                    }
21006                }
21007            }
21008        }
21009
21010        return proc;
21011    }
21012
21013    public boolean dumpHeap(String process, int userId, boolean managed,
21014            String path, ParcelFileDescriptor fd) throws RemoteException {
21015
21016        try {
21017            synchronized (this) {
21018                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21019                // its own permission (same as profileControl).
21020                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21021                        != PackageManager.PERMISSION_GRANTED) {
21022                    throw new SecurityException("Requires permission "
21023                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21024                }
21025
21026                if (fd == null) {
21027                    throw new IllegalArgumentException("null fd");
21028                }
21029
21030                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21031                if (proc == null || proc.thread == null) {
21032                    throw new IllegalArgumentException("Unknown process: " + process);
21033                }
21034
21035                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21036                if (!isDebuggable) {
21037                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21038                        throw new SecurityException("Process not debuggable: " + proc);
21039                    }
21040                }
21041
21042                proc.thread.dumpHeap(managed, path, fd);
21043                fd = null;
21044                return true;
21045            }
21046        } catch (RemoteException e) {
21047            throw new IllegalStateException("Process disappeared");
21048        } finally {
21049            if (fd != null) {
21050                try {
21051                    fd.close();
21052                } catch (IOException e) {
21053                }
21054            }
21055        }
21056    }
21057
21058    @Override
21059    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21060            String reportPackage) {
21061        if (processName != null) {
21062            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21063                    "setDumpHeapDebugLimit()");
21064        } else {
21065            synchronized (mPidsSelfLocked) {
21066                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21067                if (proc == null) {
21068                    throw new SecurityException("No process found for calling pid "
21069                            + Binder.getCallingPid());
21070                }
21071                if (!Build.IS_DEBUGGABLE
21072                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21073                    throw new SecurityException("Not running a debuggable build");
21074                }
21075                processName = proc.processName;
21076                uid = proc.uid;
21077                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21078                    throw new SecurityException("Package " + reportPackage + " is not running in "
21079                            + proc);
21080                }
21081            }
21082        }
21083        synchronized (this) {
21084            if (maxMemSize > 0) {
21085                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21086            } else {
21087                if (uid != 0) {
21088                    mMemWatchProcesses.remove(processName, uid);
21089                } else {
21090                    mMemWatchProcesses.getMap().remove(processName);
21091                }
21092            }
21093        }
21094    }
21095
21096    @Override
21097    public void dumpHeapFinished(String path) {
21098        synchronized (this) {
21099            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21100                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21101                        + " does not match last pid " + mMemWatchDumpPid);
21102                return;
21103            }
21104            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21105                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21106                        + " does not match last path " + mMemWatchDumpFile);
21107                return;
21108            }
21109            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21110            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21111        }
21112    }
21113
21114    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21115    public void monitor() {
21116        synchronized (this) { }
21117    }
21118
21119    void onCoreSettingsChange(Bundle settings) {
21120        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21121            ProcessRecord processRecord = mLruProcesses.get(i);
21122            try {
21123                if (processRecord.thread != null) {
21124                    processRecord.thread.setCoreSettings(settings);
21125                }
21126            } catch (RemoteException re) {
21127                /* ignore */
21128            }
21129        }
21130    }
21131
21132    // Multi-user methods
21133
21134    /**
21135     * Start user, if its not already running, but don't bring it to foreground.
21136     */
21137    @Override
21138    public boolean startUserInBackground(final int userId) {
21139        return mUserController.startUser(userId, /* foreground */ false);
21140    }
21141
21142    @Override
21143    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21144        return mUserController.unlockUser(userId, token, secret, listener);
21145    }
21146
21147    @Override
21148    public boolean switchUser(final int targetUserId) {
21149        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21150        UserInfo currentUserInfo;
21151        UserInfo targetUserInfo;
21152        synchronized (this) {
21153            int currentUserId = mUserController.getCurrentUserIdLocked();
21154            currentUserInfo = mUserController.getUserInfo(currentUserId);
21155            targetUserInfo = mUserController.getUserInfo(targetUserId);
21156            if (targetUserInfo == null) {
21157                Slog.w(TAG, "No user info for user #" + targetUserId);
21158                return false;
21159            }
21160            if (!targetUserInfo.supportsSwitchTo()) {
21161                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21162                return false;
21163            }
21164            if (targetUserInfo.isManagedProfile()) {
21165                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21166                return false;
21167            }
21168            mUserController.setTargetUserIdLocked(targetUserId);
21169        }
21170        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21171        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21172        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21173        return true;
21174    }
21175
21176    void scheduleStartProfilesLocked() {
21177        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21178            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21179                    DateUtils.SECOND_IN_MILLIS);
21180        }
21181    }
21182
21183    @Override
21184    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21185        return mUserController.stopUser(userId, force, callback);
21186    }
21187
21188    @Override
21189    public UserInfo getCurrentUser() {
21190        return mUserController.getCurrentUser();
21191    }
21192
21193    @Override
21194    public boolean isUserRunning(int userId, int flags) {
21195        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21196                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21197            String msg = "Permission Denial: isUserRunning() from pid="
21198                    + Binder.getCallingPid()
21199                    + ", uid=" + Binder.getCallingUid()
21200                    + " requires " + INTERACT_ACROSS_USERS;
21201            Slog.w(TAG, msg);
21202            throw new SecurityException(msg);
21203        }
21204        synchronized (this) {
21205            return mUserController.isUserRunningLocked(userId, flags);
21206        }
21207    }
21208
21209    @Override
21210    public int[] getRunningUserIds() {
21211        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21212                != PackageManager.PERMISSION_GRANTED) {
21213            String msg = "Permission Denial: isUserRunning() from pid="
21214                    + Binder.getCallingPid()
21215                    + ", uid=" + Binder.getCallingUid()
21216                    + " requires " + INTERACT_ACROSS_USERS;
21217            Slog.w(TAG, msg);
21218            throw new SecurityException(msg);
21219        }
21220        synchronized (this) {
21221            return mUserController.getStartedUserArrayLocked();
21222        }
21223    }
21224
21225    @Override
21226    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21227        mUserController.registerUserSwitchObserver(observer);
21228    }
21229
21230    @Override
21231    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21232        mUserController.unregisterUserSwitchObserver(observer);
21233    }
21234
21235    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21236        if (info == null) return null;
21237        ApplicationInfo newInfo = new ApplicationInfo(info);
21238        newInfo.initForUser(userId);
21239        return newInfo;
21240    }
21241
21242    public boolean isUserStopped(int userId) {
21243        synchronized (this) {
21244            return mUserController.getStartedUserStateLocked(userId) == null;
21245        }
21246    }
21247
21248    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21249        if (aInfo == null
21250                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21251            return aInfo;
21252        }
21253
21254        ActivityInfo info = new ActivityInfo(aInfo);
21255        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21256        return info;
21257    }
21258
21259    private boolean processSanityChecksLocked(ProcessRecord process) {
21260        if (process == null || process.thread == null) {
21261            return false;
21262        }
21263
21264        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21265        if (!isDebuggable) {
21266            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21267                return false;
21268            }
21269        }
21270
21271        return true;
21272    }
21273
21274    public boolean startBinderTracking() throws RemoteException {
21275        synchronized (this) {
21276            mBinderTransactionTrackingEnabled = true;
21277            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21278            // permission (same as profileControl).
21279            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21280                    != PackageManager.PERMISSION_GRANTED) {
21281                throw new SecurityException("Requires permission "
21282                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21283            }
21284
21285            for (int i = 0; i < mLruProcesses.size(); i++) {
21286                ProcessRecord process = mLruProcesses.get(i);
21287                if (!processSanityChecksLocked(process)) {
21288                    continue;
21289                }
21290                try {
21291                    process.thread.startBinderTracking();
21292                } catch (RemoteException e) {
21293                    Log.v(TAG, "Process disappared");
21294                }
21295            }
21296            return true;
21297        }
21298    }
21299
21300    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21301        try {
21302            synchronized (this) {
21303                mBinderTransactionTrackingEnabled = false;
21304                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21305                // permission (same as profileControl).
21306                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21307                        != PackageManager.PERMISSION_GRANTED) {
21308                    throw new SecurityException("Requires permission "
21309                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21310                }
21311
21312                if (fd == null) {
21313                    throw new IllegalArgumentException("null fd");
21314                }
21315
21316                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21317                pw.println("Binder transaction traces for all processes.\n");
21318                for (ProcessRecord process : mLruProcesses) {
21319                    if (!processSanityChecksLocked(process)) {
21320                        continue;
21321                    }
21322
21323                    pw.println("Traces for process: " + process.processName);
21324                    pw.flush();
21325                    try {
21326                        TransferPipe tp = new TransferPipe();
21327                        try {
21328                            process.thread.stopBinderTrackingAndDump(
21329                                    tp.getWriteFd().getFileDescriptor());
21330                            tp.go(fd.getFileDescriptor());
21331                        } finally {
21332                            tp.kill();
21333                        }
21334                    } catch (IOException e) {
21335                        pw.println("Failure while dumping IPC traces from " + process +
21336                                ".  Exception: " + e);
21337                        pw.flush();
21338                    } catch (RemoteException e) {
21339                        pw.println("Got a RemoteException while dumping IPC traces from " +
21340                                process + ".  Exception: " + e);
21341                        pw.flush();
21342                    }
21343                }
21344                fd = null;
21345                return true;
21346            }
21347        } finally {
21348            if (fd != null) {
21349                try {
21350                    fd.close();
21351                } catch (IOException e) {
21352                }
21353            }
21354        }
21355    }
21356
21357    private final class LocalService extends ActivityManagerInternal {
21358        @Override
21359        public void onWakefulnessChanged(int wakefulness) {
21360            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21361        }
21362
21363        @Override
21364        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21365                String processName, String abiOverride, int uid, Runnable crashHandler) {
21366            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21367                    processName, abiOverride, uid, crashHandler);
21368        }
21369
21370        @Override
21371        public SleepToken acquireSleepToken(String tag) {
21372            Preconditions.checkNotNull(tag);
21373
21374            synchronized (ActivityManagerService.this) {
21375                SleepTokenImpl token = new SleepTokenImpl(tag);
21376                mSleepTokens.add(token);
21377                updateSleepIfNeededLocked();
21378                applyVrModeIfNeededLocked(mFocusedActivity, false);
21379                return token;
21380            }
21381        }
21382
21383        @Override
21384        public ComponentName getHomeActivityForUser(int userId) {
21385            synchronized (ActivityManagerService.this) {
21386                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21387                return homeActivity == null ? null : homeActivity.realActivity;
21388            }
21389        }
21390
21391        @Override
21392        public void onUserRemoved(int userId) {
21393            synchronized (ActivityManagerService.this) {
21394                ActivityManagerService.this.onUserStoppedLocked(userId);
21395            }
21396        }
21397
21398        @Override
21399        public void onLocalVoiceInteractionStarted(IBinder activity,
21400                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21401            synchronized (ActivityManagerService.this) {
21402                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21403                        voiceSession, voiceInteractor);
21404            }
21405        }
21406
21407        @Override
21408        public void notifyStartingWindowDrawn() {
21409            synchronized (ActivityManagerService.this) {
21410                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21411            }
21412        }
21413
21414        @Override
21415        public void notifyAppTransitionStarting(int reason) {
21416            synchronized (ActivityManagerService.this) {
21417                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21418            }
21419        }
21420
21421        @Override
21422        public void notifyAppTransitionFinished() {
21423            synchronized (ActivityManagerService.this) {
21424                mStackSupervisor.notifyAppTransitionDone();
21425            }
21426        }
21427
21428        @Override
21429        public void notifyAppTransitionCancelled() {
21430            synchronized (ActivityManagerService.this) {
21431                mStackSupervisor.notifyAppTransitionDone();
21432            }
21433        }
21434
21435        @Override
21436        public List<IBinder> getTopVisibleActivities() {
21437            synchronized (ActivityManagerService.this) {
21438                return mStackSupervisor.getTopVisibleActivities();
21439            }
21440        }
21441
21442        @Override
21443        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21444            synchronized (ActivityManagerService.this) {
21445                mStackSupervisor.setDockedStackMinimized(minimized);
21446            }
21447        }
21448
21449        @Override
21450        public void killForegroundAppsForUser(int userHandle) {
21451            synchronized (ActivityManagerService.this) {
21452                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21453                final int NP = mProcessNames.getMap().size();
21454                for (int ip = 0; ip < NP; ip++) {
21455                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21456                    final int NA = apps.size();
21457                    for (int ia = 0; ia < NA; ia++) {
21458                        final ProcessRecord app = apps.valueAt(ia);
21459                        if (app.persistent) {
21460                            // We don't kill persistent processes.
21461                            continue;
21462                        }
21463                        if (app.removed) {
21464                            procs.add(app);
21465                        } else if (app.userId == userHandle && app.foregroundActivities) {
21466                            app.removed = true;
21467                            procs.add(app);
21468                        }
21469                    }
21470                }
21471
21472                final int N = procs.size();
21473                for (int i = 0; i < N; i++) {
21474                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21475                }
21476            }
21477        }
21478
21479        @Override
21480        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21481            if (!(target instanceof PendingIntentRecord)) {
21482                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21483                return;
21484            }
21485            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21486        }
21487    }
21488
21489    private final class SleepTokenImpl extends SleepToken {
21490        private final String mTag;
21491        private final long mAcquireTime;
21492
21493        public SleepTokenImpl(String tag) {
21494            mTag = tag;
21495            mAcquireTime = SystemClock.uptimeMillis();
21496        }
21497
21498        @Override
21499        public void release() {
21500            synchronized (ActivityManagerService.this) {
21501                if (mSleepTokens.remove(this)) {
21502                    updateSleepIfNeededLocked();
21503                }
21504            }
21505        }
21506
21507        @Override
21508        public String toString() {
21509            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21510        }
21511    }
21512
21513    /**
21514     * An implementation of IAppTask, that allows an app to manage its own tasks via
21515     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21516     * only the process that calls getAppTasks() can call the AppTask methods.
21517     */
21518    class AppTaskImpl extends IAppTask.Stub {
21519        private int mTaskId;
21520        private int mCallingUid;
21521
21522        public AppTaskImpl(int taskId, int callingUid) {
21523            mTaskId = taskId;
21524            mCallingUid = callingUid;
21525        }
21526
21527        private void checkCaller() {
21528            if (mCallingUid != Binder.getCallingUid()) {
21529                throw new SecurityException("Caller " + mCallingUid
21530                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21531            }
21532        }
21533
21534        @Override
21535        public void finishAndRemoveTask() {
21536            checkCaller();
21537
21538            synchronized (ActivityManagerService.this) {
21539                long origId = Binder.clearCallingIdentity();
21540                try {
21541                    // We remove the task from recents to preserve backwards
21542                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21543                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21544                    }
21545                } finally {
21546                    Binder.restoreCallingIdentity(origId);
21547                }
21548            }
21549        }
21550
21551        @Override
21552        public ActivityManager.RecentTaskInfo getTaskInfo() {
21553            checkCaller();
21554
21555            synchronized (ActivityManagerService.this) {
21556                long origId = Binder.clearCallingIdentity();
21557                try {
21558                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21559                    if (tr == null) {
21560                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21561                    }
21562                    return createRecentTaskInfoFromTaskRecord(tr);
21563                } finally {
21564                    Binder.restoreCallingIdentity(origId);
21565                }
21566            }
21567        }
21568
21569        @Override
21570        public void moveToFront() {
21571            checkCaller();
21572            // Will bring task to front if it already has a root activity.
21573            final long origId = Binder.clearCallingIdentity();
21574            try {
21575                synchronized (this) {
21576                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21577                }
21578            } finally {
21579                Binder.restoreCallingIdentity(origId);
21580            }
21581        }
21582
21583        @Override
21584        public int startActivity(IBinder whoThread, String callingPackage,
21585                Intent intent, String resolvedType, Bundle bOptions) {
21586            checkCaller();
21587
21588            int callingUser = UserHandle.getCallingUserId();
21589            TaskRecord tr;
21590            IApplicationThread appThread;
21591            synchronized (ActivityManagerService.this) {
21592                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21593                if (tr == null) {
21594                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21595                }
21596                appThread = ApplicationThreadNative.asInterface(whoThread);
21597                if (appThread == null) {
21598                    throw new IllegalArgumentException("Bad app thread " + appThread);
21599                }
21600            }
21601            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21602                    resolvedType, null, null, null, null, 0, 0, null, null,
21603                    null, bOptions, false, callingUser, null, tr);
21604        }
21605
21606        @Override
21607        public void setExcludeFromRecents(boolean exclude) {
21608            checkCaller();
21609
21610            synchronized (ActivityManagerService.this) {
21611                long origId = Binder.clearCallingIdentity();
21612                try {
21613                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21614                    if (tr == null) {
21615                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21616                    }
21617                    Intent intent = tr.getBaseIntent();
21618                    if (exclude) {
21619                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21620                    } else {
21621                        intent.setFlags(intent.getFlags()
21622                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21623                    }
21624                } finally {
21625                    Binder.restoreCallingIdentity(origId);
21626                }
21627            }
21628        }
21629    }
21630
21631    /**
21632     * Kill processes for the user with id userId and that depend on the package named packageName
21633     */
21634    @Override
21635    public void killPackageDependents(String packageName, int userId) {
21636        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21637        if (packageName == null) {
21638            throw new NullPointerException(
21639                    "Cannot kill the dependents of a package without its name.");
21640        }
21641
21642        long callingId = Binder.clearCallingIdentity();
21643        IPackageManager pm = AppGlobals.getPackageManager();
21644        int pkgUid = -1;
21645        try {
21646            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21647        } catch (RemoteException e) {
21648        }
21649        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21650            throw new IllegalArgumentException(
21651                    "Cannot kill dependents of non-existing package " + packageName);
21652        }
21653        try {
21654            synchronized(this) {
21655                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21656                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21657                        "dep: " + packageName);
21658            }
21659        } finally {
21660            Binder.restoreCallingIdentity(callingId);
21661        }
21662    }
21663}
21664