ActivityManagerService.java revision 9b80b94167a7d218da28b357d1daabf5ab1f309d
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_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519    static final int FIRST_COMPAT_MODE_MSG = 300;
1520    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522    static ServiceThread sKillThread = null;
1523    static KillHandler sKillHandler = null;
1524
1525    CompatModeDialog mCompatModeDialog;
1526    long mLastMemUsageReportTime = 0;
1527
1528    /**
1529     * Flag whether the current user is a "monkey", i.e. whether
1530     * the UI is driven by a UI automation tool.
1531     */
1532    private boolean mUserIsMonkey;
1533
1534    /** Flag whether the device has a Recents UI */
1535    boolean mHasRecents;
1536
1537    /** The dimensions of the thumbnails in the Recents UI. */
1538    int mThumbnailWidth;
1539    int mThumbnailHeight;
1540    float mFullscreenThumbnailScale;
1541
1542    final ServiceThread mHandlerThread;
1543    final MainHandler mHandler;
1544    final UiHandler mUiHandler;
1545
1546    PackageManagerInternal mPackageManagerInt;
1547
1548    // VoiceInteraction session ID that changes for each new request except when
1549    // being called for multiwindow assist in a single session.
1550    private int mViSessionId = 1000;
1551
1552    final class KillHandler extends Handler {
1553        static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555        public KillHandler(Looper looper) {
1556            super(looper, null, true);
1557        }
1558
1559        @Override
1560        public void handleMessage(Message msg) {
1561            switch (msg.what) {
1562                case KILL_PROCESS_GROUP_MSG:
1563                {
1564                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                }
1568                break;
1569
1570                default:
1571                    super.handleMessage(msg);
1572            }
1573        }
1574    }
1575
1576    final class UiHandler extends Handler {
1577        public UiHandler() {
1578            super(com.android.server.UiThread.get().getLooper(), null, true);
1579        }
1580
1581        @Override
1582        public void handleMessage(Message msg) {
1583            switch (msg.what) {
1584            case SHOW_ERROR_UI_MSG: {
1585                mAppErrors.handleShowAppErrorUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_NOT_RESPONDING_UI_MSG: {
1589                mAppErrors.handleShowAnrUi(msg);
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord proc = (ProcessRecord) data.get("app");
1596                    if (proc == null) {
1597                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                        break;
1599                    }
1600                    if (proc.crashDialog != null) {
1601                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                        return;
1603                    }
1604                    AppErrorResult res = (AppErrorResult) data.get("result");
1605                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                        Dialog d = new StrictModeViolationDialog(mContext,
1607                                ActivityManagerService.this, res, proc);
1608                        d.show();
1609                        proc.crashDialog = d;
1610                    } else {
1611                        // The device is asleep, so just pretend that the user
1612                        // saw a crash dialog and hit "force quit".
1613                        res.set(0);
1614                    }
1615                }
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_FACTORY_ERROR_UI_MSG: {
1619                Dialog d = new FactoryErrorDialog(
1620                    mContext, msg.getData().getCharSequence("msg"));
1621                d.show();
1622                ensureBootCompleted();
1623            } break;
1624            case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ProcessRecord app = (ProcessRecord)msg.obj;
1627                    if (msg.arg1 != 0) {
1628                        if (!app.waitedForDebugger) {
1629                            Dialog d = new AppWaitingForDebuggerDialog(
1630                                    ActivityManagerService.this,
1631                                    mContext, app);
1632                            app.waitDialog = d;
1633                            app.waitedForDebugger = true;
1634                            d.show();
1635                        }
1636                    } else {
1637                        if (app.waitDialog != null) {
1638                            app.waitDialog.dismiss();
1639                            app.waitDialog = null;
1640                        }
1641                    }
1642                }
1643            } break;
1644            case SHOW_UID_ERROR_UI_MSG: {
1645                if (mShowDialogs) {
1646                    AlertDialog d = new BaseErrorDialog(mContext);
1647                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                    d.setCancelable(false);
1649                    d.setTitle(mContext.getText(R.string.android_system_label));
1650                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                    d.show();
1654                }
1655            } break;
1656            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                if (mShowDialogs) {
1658                    AlertDialog d = new BaseErrorDialog(mContext);
1659                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                    d.setCancelable(false);
1661                    d.setTitle(mContext.getText(R.string.android_system_label));
1662                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                    d.show();
1666                }
1667            } break;
1668            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                synchronized (ActivityManagerService.this) {
1670                    ActivityRecord ar = (ActivityRecord) msg.obj;
1671                    if (mCompatModeDialog != null) {
1672                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                ar.info.applicationInfo.packageName)) {
1674                            return;
1675                        }
1676                        mCompatModeDialog.dismiss();
1677                        mCompatModeDialog = null;
1678                    }
1679                    if (ar != null && false) {
1680                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                ar.packageName)) {
1682                            int mode = mCompatModePackages.computeCompatModeLocked(
1683                                    ar.info.applicationInfo);
1684                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                mCompatModeDialog = new CompatModeDialog(
1687                                        ActivityManagerService.this, mContext,
1688                                        ar.info.applicationInfo);
1689                                mCompatModeDialog.show();
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case START_USER_SWITCH_UI_MSG: {
1697                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                break;
1699            }
1700            case DISMISS_DIALOG_UI_MSG: {
1701                final Dialog d = (Dialog) msg.obj;
1702                d.dismiss();
1703                break;
1704            }
1705            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                dispatchProcessesChanged();
1707                break;
1708            }
1709            case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                final int pid = msg.arg1;
1711                final int uid = msg.arg2;
1712                dispatchProcessDied(pid, uid);
1713                break;
1714            }
1715            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                dispatchUidsChanged();
1717            } break;
1718            }
1719        }
1720    }
1721
1722    final class MainHandler extends Handler {
1723        public MainHandler(Looper looper) {
1724            super(looper, null, true);
1725        }
1726
1727        @Override
1728        public void handleMessage(Message msg) {
1729            switch (msg.what) {
1730            case UPDATE_CONFIGURATION_MSG: {
1731                final ContentResolver resolver = mContext.getContentResolver();
1732                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                        msg.arg1);
1734            } break;
1735            case GC_BACKGROUND_PROCESSES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    performAppGcsIfAppropriateLocked();
1738                }
1739            } break;
1740            case SERVICE_TIMEOUT_MSG: {
1741                if (mDidDexOpt) {
1742                    mDidDexOpt = false;
1743                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                    nmsg.obj = msg.obj;
1745                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                    return;
1747                }
1748                mServices.serviceTimeout((ProcessRecord)msg.obj);
1749            } break;
1750            case UPDATE_TIME_ZONE: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimeZone();
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763            } break;
1764            case CLEAR_DNS_CACHE_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.clearDnsCache();
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case UPDATE_HTTP_PROXY_MSG: {
1779                ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                String host = "";
1781                String port = "";
1782                String exclList = "";
1783                Uri pacFileUrl = Uri.EMPTY;
1784                if (proxy != null) {
1785                    host = proxy.getHost();
1786                    port = Integer.toString(proxy.getPort());
1787                    exclList = proxy.getExclusionListAsString();
1788                    pacFileUrl = proxy.getPacFileUrl();
1789                }
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update http proxy for: " +
1798                                        r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case PROC_START_TIMEOUT_MSG: {
1805                if (mDidDexOpt) {
1806                    mDidDexOpt = false;
1807                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                    nmsg.obj = msg.obj;
1809                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                    return;
1811                }
1812                ProcessRecord app = (ProcessRecord)msg.obj;
1813                synchronized (ActivityManagerService.this) {
1814                    processStartTimedOutLocked(app);
1815                }
1816            } break;
1817            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                ProcessRecord app = (ProcessRecord)msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    processContentProviderPublishTimedOutLocked(app);
1821                }
1822            } break;
1823            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                }
1827            } break;
1828            case KILL_APPLICATION_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    int appid = msg.arg1;
1831                    boolean restart = (msg.arg2 == 1);
1832                    Bundle bundle = (Bundle)msg.obj;
1833                    String pkg = bundle.getString("pkg");
1834                    String reason = bundle.getString("reason");
1835                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                            false, UserHandle.USER_ALL, reason);
1837                }
1838            } break;
1839            case FINALIZE_PENDING_INTENT_MSG: {
1840                ((PendingIntentRecord)msg.obj).completeFinalize();
1841            } break;
1842            case POST_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847
1848                ActivityRecord root = (ActivityRecord)msg.obj;
1849                ProcessRecord process = root.app;
1850                if (process == null) {
1851                    return;
1852                }
1853
1854                try {
1855                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                    String text = mContext.getString(R.string.heavy_weight_notification,
1857                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                    Notification notification = new Notification.Builder(context)
1859                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                            .setWhen(0)
1861                            .setOngoing(true)
1862                            .setTicker(text)
1863                            .setColor(mContext.getColor(
1864                                    com.android.internal.R.color.system_notification_accent_color))
1865                            .setContentTitle(text)
1866                            .setContentText(
1867                                    mContext.getText(R.string.heavy_weight_notification_detail))
1868                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                    new UserHandle(root.userId)))
1871                            .build();
1872                    try {
1873                        int[] outId = new int[1];
1874                        inm.enqueueNotificationWithTag("android", "android", null,
1875                                R.string.heavy_weight_notification,
1876                                notification, outId, root.userId);
1877                    } catch (RuntimeException e) {
1878                        Slog.w(ActivityManagerService.TAG,
1879                                "Error showing notification for heavy-weight app", e);
1880                    } catch (RemoteException e) {
1881                    }
1882                } catch (NameNotFoundException e) {
1883                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                }
1885            } break;
1886            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891                try {
1892                    inm.cancelNotificationWithTag("android", null,
1893                            R.string.heavy_weight_notification,  msg.arg1);
1894                } catch (RuntimeException e) {
1895                    Slog.w(ActivityManagerService.TAG,
1896                            "Error canceling notification for service", e);
1897                } catch (RemoteException e) {
1898                }
1899            } break;
1900            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    checkExcessivePowerUsageLocked(true);
1903                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                }
1907            } break;
1908            case REPORT_MEM_USAGE_MSG: {
1909                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                Thread thread = new Thread() {
1911                    @Override public void run() {
1912                        reportMemUsage(memInfos);
1913                    }
1914                };
1915                thread.start();
1916                break;
1917            }
1918            case REPORT_USER_SWITCH_MSG: {
1919                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case CONTINUE_USER_SWITCH_MSG: {
1923                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case USER_SWITCH_TIMEOUT_MSG: {
1927                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                break;
1929            }
1930            case IMMERSIVE_MODE_LOCK_MSG: {
1931                final boolean nextState = (msg.arg1 != 0);
1932                if (mUpdateLock.isHeld() != nextState) {
1933                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                            "Applying new update lock state '" + nextState
1935                            + "' for " + (ActivityRecord)msg.obj);
1936                    if (nextState) {
1937                        mUpdateLock.acquire();
1938                    } else {
1939                        mUpdateLock.release();
1940                    }
1941                }
1942                break;
1943            }
1944            case PERSIST_URI_GRANTS_MSG: {
1945                writeGrantedUriPermissions();
1946                break;
1947            }
1948            case REQUEST_ALL_PSS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                }
1952                break;
1953            }
1954            case START_PROFILES_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    mUserController.startProfilesLocked();
1957                }
1958                break;
1959            }
1960            case UPDATE_TIME: {
1961                synchronized (ActivityManagerService.this) {
1962                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                        ProcessRecord r = mLruProcesses.get(i);
1964                        if (r.thread != null) {
1965                            try {
1966                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                            } catch (RemoteException ex) {
1968                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                            }
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case SYSTEM_USER_START_MSG: {
1976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                        Integer.toString(msg.arg1), msg.arg1);
1978                mSystemServiceManager.startUser(msg.arg1);
1979                break;
1980            }
1981            case SYSTEM_USER_UNLOCK_MSG: {
1982                final int userId = msg.arg1;
1983                mSystemServiceManager.unlockUser(userId);
1984                synchronized (ActivityManagerService.this) {
1985                    mRecentTasks.loadUserRecentsLocked(userId);
1986                }
1987                if (userId == UserHandle.USER_SYSTEM) {
1988                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                }
1990                installEncryptionUnawareProviders(userId);
1991                mUserController.finishUserUnlocked((UserState) msg.obj);
1992                break;
1993            }
1994            case SYSTEM_USER_CURRENT_MSG: {
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                        Integer.toString(msg.arg2), msg.arg2);
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                        Integer.toString(msg.arg1), msg.arg1);
2001                mSystemServiceManager.switchUser(msg.arg1);
2002                break;
2003            }
2004            case ENTER_ANIMATION_COMPLETE_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                    if (r != null && r.app != null && r.app.thread != null) {
2008                        try {
2009                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                        } catch (RemoteException e) {
2011                        }
2012                    }
2013                }
2014                break;
2015            }
2016            case FINISH_BOOTING_MSG: {
2017                if (msg.arg1 != 0) {
2018                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                    finishBooting();
2020                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                }
2022                if (msg.arg2 != 0) {
2023                    enableScreenAfterBoot();
2024                }
2025                break;
2026            }
2027            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                try {
2029                    Locale l = (Locale) msg.obj;
2030                    IBinder service = ServiceManager.getService("mount");
2031                    IMountService mountService = IMountService.Stub.asInterface(service);
2032                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                } catch (RemoteException e) {
2035                    Log.e(TAG, "Error storing locale for decryption UI", e);
2036                }
2037                break;
2038            }
2039            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                        } catch (RemoteException e){
2060                            // Handled by the RemoteCallbackList
2061                        }
2062                    }
2063                    mTaskStackListeners.finishBroadcast();
2064                }
2065                break;
2066            }
2067            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                        try {
2071                            // Make a one-way callback to the listener
2072                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                        } catch (RemoteException e){
2074                            // Handled by the RemoteCallbackList
2075                        }
2076                    }
2077                    mTaskStackListeners.finishBroadcast();
2078                }
2079                break;
2080            }
2081            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                    (String) msg.obj, msg.arg1);
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                    synchronized (ActivityManagerService.this) {
2112                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                            try {
2114                                // Make a one-way callback to the listener
2115                                mTaskStackListeners.getBroadcastItem(i)
2116                                        .onActivityDismissingDockedStack();
2117                            } catch (RemoteException e){
2118                                // Handled by the RemoteCallbackList
2119                            }
2120                        }
2121                        mTaskStackListeners.finishBroadcast();
2122                    }
2123                    break;
2124                }
2125            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                final int uid = msg.arg1;
2127                final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                synchronized (mPidsSelfLocked) {
2130                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                        if (p.uid == uid) {
2133                            try {
2134                                p.thread.notifyCleartextNetwork(firstPacket);
2135                            } catch (RemoteException ignored) {
2136                            }
2137                        }
2138                    }
2139                }
2140                break;
2141            }
2142            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                final String procName;
2144                final int uid;
2145                final long memLimit;
2146                final String reportPackage;
2147                synchronized (ActivityManagerService.this) {
2148                    procName = mMemWatchDumpProcName;
2149                    uid = mMemWatchDumpUid;
2150                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                    if (val == null) {
2152                        val = mMemWatchProcesses.get(procName, 0);
2153                    }
2154                    if (val != null) {
2155                        memLimit = val.first;
2156                        reportPackage = val.second;
2157                    } else {
2158                        memLimit = 0;
2159                        reportPackage = null;
2160                    }
2161                }
2162                if (procName == null) {
2163                    return;
2164                }
2165
2166                if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                        "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                INotificationManager inm = NotificationManager.getService();
2170                if (inm == null) {
2171                    return;
2172                }
2173
2174                String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                Intent deleteIntent = new Intent();
2178                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                Intent intent = new Intent();
2180                intent.setClassName("android", DumpHeapActivity.class.getName());
2181                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                if (reportPackage != null) {
2184                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                }
2186                int userId = UserHandle.getUserId(uid);
2187                Notification notification = new Notification.Builder(mContext)
2188                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                        .setWhen(0)
2190                        .setOngoing(true)
2191                        .setAutoCancel(true)
2192                        .setTicker(text)
2193                        .setColor(mContext.getColor(
2194                                com.android.internal.R.color.system_notification_accent_color))
2195                        .setContentTitle(text)
2196                        .setContentText(
2197                                mContext.getText(R.string.dump_heap_notification_detail))
2198                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                new UserHandle(userId)))
2201                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                deleteIntent, 0, UserHandle.SYSTEM))
2203                        .build();
2204
2205                try {
2206                    int[] outId = new int[1];
2207                    inm.enqueueNotificationWithTag("android", "android", null,
2208                            R.string.dump_heap_notification,
2209                            notification, outId, userId);
2210                } catch (RuntimeException e) {
2211                    Slog.w(ActivityManagerService.TAG,
2212                            "Error showing notification for dump heap", e);
2213                } catch (RemoteException e) {
2214                }
2215            } break;
2216            case DELETE_DUMPHEAP_MSG: {
2217                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                        DumpHeapActivity.JAVA_URI,
2219                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                        UserHandle.myUserId());
2222                synchronized (ActivityManagerService.this) {
2223                    mMemWatchDumpFile = null;
2224                    mMemWatchDumpProcName = null;
2225                    mMemWatchDumpPid = -1;
2226                    mMemWatchDumpUid = -1;
2227                }
2228            } break;
2229            case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231            } break;
2232            case REPORT_TIME_TRACKER_MSG: {
2233                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                tracker.deliverResult(mContext);
2235            } break;
2236            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                mUserController.dispatchUserSwitchComplete(msg.arg1);
2238            } break;
2239            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                try {
2242                    connection.shutdown();
2243                } catch (RemoteException e) {
2244                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                }
2246                // Only a UiAutomation can set this flag and now that
2247                // it is finished we make sure it is reset to its default.
2248                mUserIsMonkey = false;
2249            } break;
2250            case APP_BOOST_DEACTIVATE_MSG: {
2251                synchronized(ActivityManagerService.this) {
2252                    if (mIsBoosted) {
2253                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                            nativeMigrateFromBoost();
2255                            mIsBoosted = false;
2256                            mBoostStartTime = 0;
2257                        } else {
2258                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                        }
2261                    }
2262                }
2263            } break;
2264            case IDLE_UIDS_MSG: {
2265                idleUids();
2266            } break;
2267            case LOG_STACK_STATE: {
2268                synchronized (ActivityManagerService.this) {
2269                    mStackSupervisor.logStackState();
2270                }
2271            } break;
2272            case VR_MODE_CHANGE_MSG: {
2273                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                    }
2288                }
2289                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290            } break;
2291            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                if (needsVrMode) {
2295                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2296                            r.info.getComponentName(), false);
2297                }
2298            } break;
2299            }
2300        }
2301    };
2302
2303    static final int COLLECT_PSS_BG_MSG = 1;
2304
2305    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306        @Override
2307        public void handleMessage(Message msg) {
2308            switch (msg.what) {
2309            case COLLECT_PSS_BG_MSG: {
2310                long start = SystemClock.uptimeMillis();
2311                MemInfoReader memInfo = null;
2312                synchronized (ActivityManagerService.this) {
2313                    if (mFullPssPending) {
2314                        mFullPssPending = false;
2315                        memInfo = new MemInfoReader();
2316                    }
2317                }
2318                if (memInfo != null) {
2319                    updateCpuStatsNow();
2320                    long nativeTotalPss = 0;
2321                    synchronized (mProcessCpuTracker) {
2322                        final int N = mProcessCpuTracker.countStats();
2323                        for (int j=0; j<N; j++) {
2324                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                // This is definitely an application process; skip it.
2327                                continue;
2328                            }
2329                            synchronized (mPidsSelfLocked) {
2330                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                    // This is one of our own processes; skip it.
2332                                    continue;
2333                                }
2334                            }
2335                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                        }
2337                    }
2338                    memInfo.readMemInfo();
2339                    synchronized (ActivityManagerService.this) {
2340                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                + (SystemClock.uptimeMillis()-start) + "ms");
2342                        final long cachedKb = memInfo.getCachedSizeKb();
2343                        final long freeKb = memInfo.getFreeSizeKb();
2344                        final long zramKb = memInfo.getZramTotalSizeKb();
2345                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                kernelKb*1024, nativeTotalPss*1024);
2348                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                nativeTotalPss);
2350                    }
2351                }
2352
2353                int num = 0;
2354                long[] tmp = new long[2];
2355                do {
2356                    ProcessRecord proc;
2357                    int procState;
2358                    int pid;
2359                    long lastPssTime;
2360                    synchronized (ActivityManagerService.this) {
2361                        if (mPendingPssProcesses.size() <= 0) {
2362                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                    "Collected PSS of " + num + " processes in "
2364                                    + (SystemClock.uptimeMillis() - start) + "ms");
2365                            mPendingPssProcesses.clear();
2366                            return;
2367                        }
2368                        proc = mPendingPssProcesses.remove(0);
2369                        procState = proc.pssProcState;
2370                        lastPssTime = proc.lastPssTime;
2371                        if (proc.thread != null && procState == proc.setProcState
2372                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                        < SystemClock.uptimeMillis()) {
2374                            pid = proc.pid;
2375                        } else {
2376                            proc = null;
2377                            pid = 0;
2378                        }
2379                    }
2380                    if (proc != null) {
2381                        long pss = Debug.getPss(pid, tmp, null);
2382                        synchronized (ActivityManagerService.this) {
2383                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                num++;
2386                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                        SystemClock.uptimeMillis());
2388                            }
2389                        }
2390                    }
2391                } while (true);
2392            }
2393            }
2394        }
2395    };
2396
2397    public void setSystemProcess() {
2398        try {
2399            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401            ServiceManager.addService("meminfo", new MemBinder(this));
2402            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403            ServiceManager.addService("dbinfo", new DbBinder(this));
2404            if (MONITOR_CPU_USAGE) {
2405                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406            }
2407            ServiceManager.addService("permission", new PermissionController(this));
2408            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414            synchronized (this) {
2415                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                app.persistent = true;
2417                app.pid = MY_PID;
2418                app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                synchronized (mPidsSelfLocked) {
2421                    mPidsSelfLocked.put(app.pid, app);
2422                }
2423                updateLruProcessLocked(app, false, null);
2424                updateOomAdjLocked();
2425            }
2426        } catch (PackageManager.NameNotFoundException e) {
2427            throw new RuntimeException(
2428                    "Unable to find android system package", e);
2429        }
2430    }
2431
2432    public void setWindowManager(WindowManagerService wm) {
2433        mWindowManager = wm;
2434        mStackSupervisor.setWindowManager(wm);
2435        mActivityStarter.setWindowManager(wm);
2436    }
2437
2438    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439        mUsageStatsService = usageStatsManager;
2440    }
2441
2442    public void startObservingNativeCrashes() {
2443        final NativeCrashListener ncl = new NativeCrashListener(this);
2444        ncl.start();
2445    }
2446
2447    public IAppOpsService getAppOpsService() {
2448        return mAppOpsService;
2449    }
2450
2451    static class MemBinder extends Binder {
2452        ActivityManagerService mActivityManagerService;
2453        MemBinder(ActivityManagerService activityManagerService) {
2454            mActivityManagerService = activityManagerService;
2455        }
2456
2457        @Override
2458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                    != PackageManager.PERMISSION_GRANTED) {
2461                pw.println("Permission Denial: can't dump meminfo from from pid="
2462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                        + " without permission " + android.Manifest.permission.DUMP);
2464                return;
2465            }
2466
2467            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468        }
2469    }
2470
2471    static class GraphicsBinder extends Binder {
2472        ActivityManagerService mActivityManagerService;
2473        GraphicsBinder(ActivityManagerService activityManagerService) {
2474            mActivityManagerService = activityManagerService;
2475        }
2476
2477        @Override
2478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                    != PackageManager.PERMISSION_GRANTED) {
2481                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                        + " without permission " + android.Manifest.permission.DUMP);
2484                return;
2485            }
2486
2487            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488        }
2489    }
2490
2491    static class DbBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        DbBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpDbInfo(fd, pw, args);
2508        }
2509    }
2510
2511    static class CpuBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        CpuBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                        SystemClock.uptimeMillis()));
2531            }
2532        }
2533    }
2534
2535    public static final class Lifecycle extends SystemService {
2536        private final ActivityManagerService mService;
2537
2538        public Lifecycle(Context context) {
2539            super(context);
2540            mService = new ActivityManagerService(context);
2541        }
2542
2543        @Override
2544        public void onStart() {
2545            mService.start();
2546        }
2547
2548        public ActivityManagerService getService() {
2549            return mService;
2550        }
2551    }
2552
2553    // Note: This method is invoked on the main thread but may need to attach various
2554    // handlers to other threads.  So take care to be explicit about the looper.
2555    public ActivityManagerService(Context systemContext) {
2556        mContext = systemContext;
2557        mFactoryTest = FactoryTest.getMode();
2558        mSystemThread = ActivityThread.currentActivityThread();
2559
2560        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562        mHandlerThread = new ServiceThread(TAG,
2563                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564        mHandlerThread.start();
2565        mHandler = new MainHandler(mHandlerThread.getLooper());
2566        mUiHandler = new UiHandler();
2567
2568        /* static; one-time init here */
2569        if (sKillHandler == null) {
2570            sKillThread = new ServiceThread(TAG + ":kill",
2571                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572            sKillThread.start();
2573            sKillHandler = new KillHandler(sKillThread.getLooper());
2574        }
2575
2576        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "foreground", BROADCAST_FG_TIMEOUT, false);
2578        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "background", BROADCAST_BG_TIMEOUT, true);
2580        mBroadcastQueues[0] = mFgBroadcastQueue;
2581        mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583        mServices = new ActiveServices(this);
2584        mProviderMap = new ProviderMap(this);
2585        mAppErrors = new AppErrors(mContext, this);
2586
2587        // TODO: Move creation of battery stats service outside of activity manager service.
2588        File dataDir = Environment.getDataDirectory();
2589        File systemDir = new File(dataDir, "system");
2590        systemDir.mkdirs();
2591        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592        mBatteryStatsService.getActiveStatistics().readLocked();
2593        mBatteryStatsService.scheduleWriteToDisk();
2594        mOnBattery = DEBUG_POWER ? true
2595                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596        mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                new IAppOpsCallback.Stub() {
2603                    @Override public void opChanged(int op, int uid, String packageName) {
2604                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                            if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                    != AppOpsManager.MODE_ALLOWED) {
2607                                runInBackgroundDisabled(uid);
2608                            }
2609                        }
2610                    }
2611                });
2612
2613        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615        mUserController = new UserController(this);
2616
2617        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mConfiguration.setToDefaults();
2623        mConfiguration.setLocales(LocaleList.getDefault());
2624
2625        mConfigurationSeq = mConfiguration.seq = 1;
2626        mProcessCpuTracker.init();
2627
2628        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630        mStackSupervisor = new ActivityStackSupervisor(this);
2631        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634        mProcessCpuThread = new Thread("CpuTracker") {
2635            @Override
2636            public void run() {
2637                while (true) {
2638                    try {
2639                        try {
2640                            synchronized(this) {
2641                                final long now = SystemClock.uptimeMillis();
2642                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                //        + ", write delay=" + nextWriteDelay);
2646                                if (nextWriteDelay < nextCpuDelay) {
2647                                    nextCpuDelay = nextWriteDelay;
2648                                }
2649                                if (nextCpuDelay > 0) {
2650                                    mProcessCpuMutexFree.set(true);
2651                                    this.wait(nextCpuDelay);
2652                                }
2653                            }
2654                        } catch (InterruptedException e) {
2655                        }
2656                        updateCpuStatsNow();
2657                    } catch (Exception e) {
2658                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                    }
2660                }
2661            }
2662        };
2663
2664        Watchdog.getInstance().addMonitor(this);
2665        Watchdog.getInstance().addThread(mHandler);
2666    }
2667
2668    public void setSystemServiceManager(SystemServiceManager mgr) {
2669        mSystemServiceManager = mgr;
2670    }
2671
2672    public void setInstaller(Installer installer) {
2673        mInstaller = installer;
2674    }
2675
2676    private void start() {
2677        Process.removeAllProcessGroups();
2678        mProcessCpuThread.start();
2679
2680        mBatteryStatsService.publish(mContext);
2681        mAppOpsService.publish(mContext);
2682        Slog.d("AppOps", "AppOpsService published");
2683        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684    }
2685
2686    void onUserStoppedLocked(int userId) {
2687        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688    }
2689
2690    public void initPowerManagement() {
2691        mStackSupervisor.initPowerManagement();
2692        mBatteryStatsService.initPowerManagement();
2693        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696        mVoiceWakeLock.setReferenceCounted(false);
2697    }
2698
2699    @Override
2700    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701            throws RemoteException {
2702        if (code == SYSPROPS_TRANSACTION) {
2703            // We need to tell all apps about the system property change.
2704            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705            synchronized(this) {
2706                final int NP = mProcessNames.getMap().size();
2707                for (int ip=0; ip<NP; ip++) {
2708                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                    final int NA = apps.size();
2710                    for (int ia=0; ia<NA; ia++) {
2711                        ProcessRecord app = apps.valueAt(ia);
2712                        if (app.thread != null) {
2713                            procs.add(app.thread.asBinder());
2714                        }
2715                    }
2716                }
2717            }
2718
2719            int N = procs.size();
2720            for (int i=0; i<N; i++) {
2721                Parcel data2 = Parcel.obtain();
2722                try {
2723                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                } catch (RemoteException e) {
2725                }
2726                data2.recycle();
2727            }
2728        }
2729        try {
2730            return super.onTransact(code, data, reply, flags);
2731        } catch (RuntimeException e) {
2732            // The activity manager only throws security exceptions, so let's
2733            // log all others.
2734            if (!(e instanceof SecurityException)) {
2735                Slog.wtf(TAG, "Activity Manager Crash", e);
2736            }
2737            throw e;
2738        }
2739    }
2740
2741    void updateCpuStats() {
2742        final long now = SystemClock.uptimeMillis();
2743        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744            return;
2745        }
2746        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747            synchronized (mProcessCpuThread) {
2748                mProcessCpuThread.notify();
2749            }
2750        }
2751    }
2752
2753    void updateCpuStatsNow() {
2754        synchronized (mProcessCpuTracker) {
2755            mProcessCpuMutexFree.set(false);
2756            final long now = SystemClock.uptimeMillis();
2757            boolean haveNewCpuStats = false;
2758
2759            if (MONITOR_CPU_USAGE &&
2760                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                mLastCpuTime.set(now);
2762                mProcessCpuTracker.update();
2763                if (mProcessCpuTracker.hasGoodLastStats()) {
2764                    haveNewCpuStats = true;
2765                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                    //Slog.i(TAG, "Total CPU usage: "
2767                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                    // Slog the cpu usage if the property is set.
2770                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                        int user = mProcessCpuTracker.getLastUserTime();
2772                        int system = mProcessCpuTracker.getLastSystemTime();
2773                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                        int irq = mProcessCpuTracker.getLastIrqTime();
2775                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                        int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                        int total = user + system + iowait + irq + softIrq + idle;
2779                        if (total == 0) total = 1;
2780
2781                        EventLog.writeEvent(EventLogTags.CPU,
2782                                ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                (user * 100) / total,
2784                                (system * 100) / total,
2785                                (iowait * 100) / total,
2786                                (irq * 100) / total,
2787                                (softIrq * 100) / total);
2788                    }
2789                }
2790            }
2791
2792            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793            synchronized(bstats) {
2794                synchronized(mPidsSelfLocked) {
2795                    if (haveNewCpuStats) {
2796                        if (bstats.startAddingCpuLocked()) {
2797                            int totalUTime = 0;
2798                            int totalSTime = 0;
2799                            final int N = mProcessCpuTracker.countStats();
2800                            for (int i=0; i<N; i++) {
2801                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                if (!st.working) {
2803                                    continue;
2804                                }
2805                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                totalUTime += st.rel_utime;
2807                                totalSTime += st.rel_stime;
2808                                if (pr != null) {
2809                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                    if (ps == null || !ps.isActive()) {
2811                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                pr.info.uid, pr.processName);
2813                                    }
2814                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                } else {
2817                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                    if (ps == null || !ps.isActive()) {
2819                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                bstats.mapUid(st.uid), st.name);
2821                                    }
2822                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                }
2824                            }
2825                            final int userTime = mProcessCpuTracker.getLastUserTime();
2826                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                        }
2834                    }
2835                }
2836
2837                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                    mLastWriteTime = now;
2839                    mBatteryStatsService.scheduleWriteToDisk();
2840                }
2841            }
2842        }
2843    }
2844
2845    @Override
2846    public void batteryNeedsCpuUpdate() {
2847        updateCpuStatsNow();
2848    }
2849
2850    @Override
2851    public void batteryPowerChanged(boolean onBattery) {
2852        // When plugging in, update the CPU stats first before changing
2853        // the plug state.
2854        updateCpuStatsNow();
2855        synchronized (this) {
2856            synchronized(mPidsSelfLocked) {
2857                mOnBattery = DEBUG_POWER ? true : onBattery;
2858            }
2859        }
2860    }
2861
2862    @Override
2863    public void batterySendBroadcast(Intent intent) {
2864        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                AppOpsManager.OP_NONE, null, false, false,
2866                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867    }
2868
2869    /**
2870     * Initialize the application bind args. These are passed to each
2871     * process when the bindApplication() IPC is sent to the process. They're
2872     * lazily setup to make sure the services are running when they're asked for.
2873     */
2874    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875        if (mAppBindArgs == null) {
2876            mAppBindArgs = new HashMap<>();
2877
2878            // Isolated processes won't get this optimization, so that we don't
2879            // violate the rules about which services they have access to.
2880            if (!isolated) {
2881                // Setup the application init args
2882                mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                mAppBindArgs.put(Context.ALARM_SERVICE,
2885                        ServiceManager.getService(Context.ALARM_SERVICE));
2886            }
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892        if (r == null || mFocusedActivity == r) {
2893            return false;
2894        }
2895
2896        if (!r.isFocusable()) {
2897            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898            return false;
2899        }
2900
2901        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906        mDoingSetFocusedActivity = true;
2907
2908        final ActivityRecord last = mFocusedActivity;
2909        mFocusedActivity = r;
2910        if (r.task.isApplicationTask()) {
2911            if (mCurAppTimeTracker != r.appTimeTracker) {
2912                // We are switching app tracking.  Complete the current one.
2913                if (mCurAppTimeTracker != null) {
2914                    mCurAppTimeTracker.stop();
2915                    mHandler.obtainMessage(
2916                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                    mCurAppTimeTracker = null;
2919                }
2920                if (r.appTimeTracker != null) {
2921                    mCurAppTimeTracker = r.appTimeTracker;
2922                    startTimeTrackingFocusedActivityLocked();
2923                }
2924            } else {
2925                startTimeTrackingFocusedActivityLocked();
2926            }
2927        } else {
2928            r.appTimeTracker = null;
2929        }
2930        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931        // TODO: Probably not, because we don't want to resume voice on switching
2932        // back to this activity
2933        if (r.task.voiceInteractor != null) {
2934            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935        } else {
2936            finishRunningVoiceLocked();
2937            IVoiceInteractionSession session;
2938            if (last != null && ((session = last.task.voiceSession) != null
2939                    || (session = last.voiceSession) != null)) {
2940                // We had been in a voice interaction session, but now focused has
2941                // move to something different.  Just finish the session, we can't
2942                // return to it and retain the proper state and synchronization with
2943                // the voice interaction service.
2944                finishVoiceTask(session);
2945            }
2946        }
2947        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948            mWindowManager.setFocusedApp(r.appToken, true);
2949        }
2950        applyUpdateLockStateLocked(r);
2951        applyUpdateVrModeLocked(r);
2952        if (mFocusedActivity.userId != mLastFocusedUserId) {
2953            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954            mHandler.obtainMessage(
2955                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956            mLastFocusedUserId = mFocusedActivity.userId;
2957        }
2958
2959        // Log a warning if the focused app is changed during the process. This could
2960        // indicate a problem of the focus setting logic!
2961        if (mFocusedActivity != r) Slog.w(TAG,
2962                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965        EventLogTags.writeAmFocusedActivity(
2966                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                reason);
2969        return true;
2970    }
2971
2972    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973        if (mFocusedActivity != goingAway) {
2974            return;
2975        }
2976
2977        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978        if (focusedStack != null) {
2979            final ActivityRecord top = focusedStack.topActivity();
2980            if (top != null && top.userId != mLastFocusedUserId) {
2981                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                mHandler.sendMessage(
2983                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                mLastFocusedUserId = top.userId;
2985            }
2986        }
2987
2988        // Try to move focus to another activity if possible.
2989        if (setFocusedActivityLocked(
2990                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991            return;
2992        }
2993
2994        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996        mFocusedActivity = null;
2997        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998    }
2999
3000    @Override
3001    public void setFocusedStack(int stackId) {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004        final long callingId = Binder.clearCallingIdentity();
3005        try {
3006            synchronized (this) {
3007                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                if (stack == null) {
3009                    return;
3010                }
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                }
3015            }
3016        } finally {
3017            Binder.restoreCallingIdentity(callingId);
3018        }
3019    }
3020
3021    @Override
3022    public void setFocusedTask(int taskId) {
3023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025        final long callingId = Binder.clearCallingIdentity();
3026        try {
3027            synchronized (this) {
3028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                if (task == null) {
3030                    return;
3031                }
3032                final ActivityRecord r = task.topRunningActivityLocked();
3033                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                }
3036            }
3037        } finally {
3038            Binder.restoreCallingIdentity(callingId);
3039        }
3040    }
3041
3042    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043    @Override
3044    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046        synchronized (this) {
3047            if (listener != null) {
3048                mTaskStackListeners.register(listener);
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.task.stack.notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082    }
3083
3084    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3085            ComponentName callingPackage, boolean immediate) {
3086        VrManagerInternal vrService =
3087                LocalServices.getService(VrManagerInternal.class);
3088        if (immediate) {
3089            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3090        } else {
3091            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3092        }
3093    }
3094
3095    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3096        Message msg = Message.obtain();
3097        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3098        msg.obj = r.task.askedCompatMode ? null : r;
3099        mUiHandler.sendMessage(msg);
3100    }
3101
3102    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3103            String what, Object obj, ProcessRecord srcApp) {
3104        app.lastActivityTime = now;
3105
3106        if (app.activities.size() > 0) {
3107            // Don't want to touch dependent processes that are hosting activities.
3108            return index;
3109        }
3110
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui < 0) {
3113            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3114                    + what + " " + obj + " from " + srcApp);
3115            return index;
3116        }
3117
3118        if (lrui >= index) {
3119            // Don't want to cause this to move dependent processes *back* in the
3120            // list as if they were less frequently used.
3121            return index;
3122        }
3123
3124        if (lrui >= mLruProcessActivityStart) {
3125            // Don't want to touch dependent processes that are hosting activities.
3126            return index;
3127        }
3128
3129        mLruProcesses.remove(lrui);
3130        if (index > 0) {
3131            index--;
3132        }
3133        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3134                + " in LRU list: " + app);
3135        mLruProcesses.add(index, app);
3136        return index;
3137    }
3138
3139    static void killProcessGroup(int uid, int pid) {
3140        if (sKillHandler != null) {
3141            sKillHandler.sendMessage(
3142                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3143        } else {
3144            Slog.w(TAG, "Asked to kill process group before system bringup!");
3145            Process.killProcessGroup(uid, pid);
3146        }
3147    }
3148
3149    final void removeLruProcessLocked(ProcessRecord app) {
3150        int lrui = mLruProcesses.lastIndexOf(app);
3151        if (lrui >= 0) {
3152            if (!app.killed) {
3153                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3154                Process.killProcessQuiet(app.pid);
3155                killProcessGroup(app.uid, app.pid);
3156            }
3157            if (lrui <= mLruProcessActivityStart) {
3158                mLruProcessActivityStart--;
3159            }
3160            if (lrui <= mLruProcessServiceStart) {
3161                mLruProcessServiceStart--;
3162            }
3163            mLruProcesses.remove(lrui);
3164        }
3165    }
3166
3167    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3168            ProcessRecord client) {
3169        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3170                || app.treatLikeActivity;
3171        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3172        if (!activityChange && hasActivity) {
3173            // The process has activities, so we are only allowing activity-based adjustments
3174            // to move it.  It should be kept in the front of the list with other
3175            // processes that have activities, and we don't want those to change their
3176            // order except due to activity operations.
3177            return;
3178        }
3179
3180        mLruSeq++;
3181        final long now = SystemClock.uptimeMillis();
3182        app.lastActivityTime = now;
3183
3184        // First a quick reject: if the app is already at the position we will
3185        // put it, then there is nothing to do.
3186        if (hasActivity) {
3187            final int N = mLruProcesses.size();
3188            if (N > 0 && mLruProcesses.get(N-1) == app) {
3189                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3190                return;
3191            }
3192        } else {
3193            if (mLruProcessServiceStart > 0
3194                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3195                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3196                return;
3197            }
3198        }
3199
3200        int lrui = mLruProcesses.lastIndexOf(app);
3201
3202        if (app.persistent && lrui >= 0) {
3203            // We don't care about the position of persistent processes, as long as
3204            // they are in the list.
3205            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3206            return;
3207        }
3208
3209        /* In progress: compute new position first, so we can avoid doing work
3210           if the process is not actually going to move.  Not yet working.
3211        int addIndex;
3212        int nextIndex;
3213        boolean inActivity = false, inService = false;
3214        if (hasActivity) {
3215            // Process has activities, put it at the very tipsy-top.
3216            addIndex = mLruProcesses.size();
3217            nextIndex = mLruProcessServiceStart;
3218            inActivity = true;
3219        } else if (hasService) {
3220            // Process has services, put it at the top of the service list.
3221            addIndex = mLruProcessActivityStart;
3222            nextIndex = mLruProcessServiceStart;
3223            inActivity = true;
3224            inService = true;
3225        } else  {
3226            // Process not otherwise of interest, it goes to the top of the non-service area.
3227            addIndex = mLruProcessServiceStart;
3228            if (client != null) {
3229                int clientIndex = mLruProcesses.lastIndexOf(client);
3230                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3231                        + app);
3232                if (clientIndex >= 0 && addIndex > clientIndex) {
3233                    addIndex = clientIndex;
3234                }
3235            }
3236            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3237        }
3238
3239        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3240                + mLruProcessActivityStart + "): " + app);
3241        */
3242
3243        if (lrui >= 0) {
3244            if (lrui < mLruProcessActivityStart) {
3245                mLruProcessActivityStart--;
3246            }
3247            if (lrui < mLruProcessServiceStart) {
3248                mLruProcessServiceStart--;
3249            }
3250            /*
3251            if (addIndex > lrui) {
3252                addIndex--;
3253            }
3254            if (nextIndex > lrui) {
3255                nextIndex--;
3256            }
3257            */
3258            mLruProcesses.remove(lrui);
3259        }
3260
3261        /*
3262        mLruProcesses.add(addIndex, app);
3263        if (inActivity) {
3264            mLruProcessActivityStart++;
3265        }
3266        if (inService) {
3267            mLruProcessActivityStart++;
3268        }
3269        */
3270
3271        int nextIndex;
3272        if (hasActivity) {
3273            final int N = mLruProcesses.size();
3274            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3275                // Process doesn't have activities, but has clients with
3276                // activities...  move it up, but one below the top (the top
3277                // should always have a real activity).
3278                if (DEBUG_LRU) Slog.d(TAG_LRU,
3279                        "Adding to second-top of LRU activity list: " + app);
3280                mLruProcesses.add(N - 1, app);
3281                // To keep it from spamming the LRU list (by making a bunch of clients),
3282                // we will push down any other entries owned by the app.
3283                final int uid = app.info.uid;
3284                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3285                    ProcessRecord subProc = mLruProcesses.get(i);
3286                    if (subProc.info.uid == uid) {
3287                        // We want to push this one down the list.  If the process after
3288                        // it is for the same uid, however, don't do so, because we don't
3289                        // want them internally to be re-ordered.
3290                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3291                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3292                                    "Pushing uid " + uid + " swapping at " + i + ": "
3293                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3294                            ProcessRecord tmp = mLruProcesses.get(i);
3295                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3296                            mLruProcesses.set(i - 1, tmp);
3297                            i--;
3298                        }
3299                    } else {
3300                        // A gap, we can stop here.
3301                        break;
3302                    }
3303                }
3304            } else {
3305                // Process has activities, put it at the very tipsy-top.
3306                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3307                mLruProcesses.add(app);
3308            }
3309            nextIndex = mLruProcessServiceStart;
3310        } else if (hasService) {
3311            // Process has services, put it at the top of the service list.
3312            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3313            mLruProcesses.add(mLruProcessActivityStart, app);
3314            nextIndex = mLruProcessServiceStart;
3315            mLruProcessActivityStart++;
3316        } else  {
3317            // Process not otherwise of interest, it goes to the top of the non-service area.
3318            int index = mLruProcessServiceStart;
3319            if (client != null) {
3320                // If there is a client, don't allow the process to be moved up higher
3321                // in the list than that client.
3322                int clientIndex = mLruProcesses.lastIndexOf(client);
3323                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3324                        + " when updating " + app);
3325                if (clientIndex <= lrui) {
3326                    // Don't allow the client index restriction to push it down farther in the
3327                    // list than it already is.
3328                    clientIndex = lrui;
3329                }
3330                if (clientIndex >= 0 && index > clientIndex) {
3331                    index = clientIndex;
3332                }
3333            }
3334            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3335            mLruProcesses.add(index, app);
3336            nextIndex = index-1;
3337            mLruProcessActivityStart++;
3338            mLruProcessServiceStart++;
3339        }
3340
3341        // If the app is currently using a content provider or service,
3342        // bump those processes as well.
3343        for (int j=app.connections.size()-1; j>=0; j--) {
3344            ConnectionRecord cr = app.connections.valueAt(j);
3345            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3346                    && cr.binding.service.app != null
3347                    && cr.binding.service.app.lruSeq != mLruSeq
3348                    && !cr.binding.service.app.persistent) {
3349                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3350                        "service connection", cr, app);
3351            }
3352        }
3353        for (int j=app.conProviders.size()-1; j>=0; j--) {
3354            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3355            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3356                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3357                        "provider reference", cpr, app);
3358            }
3359        }
3360    }
3361
3362    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3363        if (uid == Process.SYSTEM_UID) {
3364            // The system gets to run in any process.  If there are multiple
3365            // processes with the same uid, just pick the first (this
3366            // should never happen).
3367            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3368            if (procs == null) return null;
3369            final int procCount = procs.size();
3370            for (int i = 0; i < procCount; i++) {
3371                final int procUid = procs.keyAt(i);
3372                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3373                    // Don't use an app process or different user process for system component.
3374                    continue;
3375                }
3376                return procs.valueAt(i);
3377            }
3378        }
3379        ProcessRecord proc = mProcessNames.get(processName, uid);
3380        if (false && proc != null && !keepIfLarge
3381                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3382                && proc.lastCachedPss >= 4000) {
3383            // Turn this condition on to cause killing to happen regularly, for testing.
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        } else if (proc != null && !keepIfLarge
3389                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3390                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3391            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3392            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3393                if (proc.baseProcessTracker != null) {
3394                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3395                }
3396                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3397            }
3398        }
3399        return proc;
3400    }
3401
3402    void notifyPackageUse(String packageName, int reason) {
3403        IPackageManager pm = AppGlobals.getPackageManager();
3404        try {
3405            pm.notifyPackageUse(packageName, reason);
3406        } catch (RemoteException e) {
3407        }
3408    }
3409
3410    boolean isNextTransitionForward() {
3411        int transit = mWindowManager.getPendingAppTransition();
3412        return transit == TRANSIT_ACTIVITY_OPEN
3413                || transit == TRANSIT_TASK_OPEN
3414                || transit == TRANSIT_TASK_TO_FRONT;
3415    }
3416
3417    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3418            String processName, String abiOverride, int uid, Runnable crashHandler) {
3419        synchronized(this) {
3420            ApplicationInfo info = new ApplicationInfo();
3421            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3422            // For isolated processes, the former contains the parent's uid and the latter the
3423            // actual uid of the isolated process.
3424            // In the special case introduced by this method (which is, starting an isolated
3425            // process directly from the SystemServer without an actual parent app process) the
3426            // closest thing to a parent's uid is SYSTEM_UID.
3427            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3428            // the |isolated| logic in the ProcessRecord constructor.
3429            info.uid = Process.SYSTEM_UID;
3430            info.processName = processName;
3431            info.className = entryPoint;
3432            info.packageName = "android";
3433            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3434                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3435                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3436                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3437                    crashHandler);
3438            return proc != null ? proc.pid : 0;
3439        }
3440    }
3441
3442    final ProcessRecord startProcessLocked(String processName,
3443            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3444            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3445            boolean isolated, boolean keepIfLarge) {
3446        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3447                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3448                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3449                null /* crashHandler */);
3450    }
3451
3452    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3453            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3454            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3455            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3456        long startTime = SystemClock.elapsedRealtime();
3457        ProcessRecord app;
3458        if (!isolated) {
3459            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3460            checkTime(startTime, "startProcess: after getProcessRecord");
3461
3462            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3463                // If we are in the background, then check to see if this process
3464                // is bad.  If so, we will just silently fail.
3465                if (mAppErrors.isBadProcessLocked(info)) {
3466                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3467                            + "/" + info.processName);
3468                    return null;
3469                }
3470            } else {
3471                // When the user is explicitly starting a process, then clear its
3472                // crash count so that we won't make it bad until they see at
3473                // least one crash dialog again, and make the process good again
3474                // if it had been bad.
3475                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3476                        + "/" + info.processName);
3477                mAppErrors.resetProcessCrashTimeLocked(info);
3478                if (mAppErrors.isBadProcessLocked(info)) {
3479                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3480                            UserHandle.getUserId(info.uid), info.uid,
3481                            info.processName);
3482                    mAppErrors.clearBadProcessLocked(info);
3483                    if (app != null) {
3484                        app.bad = false;
3485                    }
3486                }
3487            }
3488        } else {
3489            // If this is an isolated process, it can't re-use an existing process.
3490            app = null;
3491        }
3492
3493        // app launch boost for big.little configurations
3494        // use cpusets to migrate freshly launched tasks to big cores
3495        synchronized(ActivityManagerService.this) {
3496            nativeMigrateToBoost();
3497            mIsBoosted = true;
3498            mBoostStartTime = SystemClock.uptimeMillis();
3499            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3500            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3501        }
3502
3503        // We don't have to do anything more if:
3504        // (1) There is an existing application record; and
3505        // (2) The caller doesn't think it is dead, OR there is no thread
3506        //     object attached to it so we know it couldn't have crashed; and
3507        // (3) There is a pid assigned to it, so it is either starting or
3508        //     already running.
3509        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3510                + " app=" + app + " knownToBeDead=" + knownToBeDead
3511                + " thread=" + (app != null ? app.thread : null)
3512                + " pid=" + (app != null ? app.pid : -1));
3513        if (app != null && app.pid > 0) {
3514            if (!knownToBeDead || app.thread == null) {
3515                // We already have the app running, or are waiting for it to
3516                // come up (we have a pid but not yet its thread), so keep it.
3517                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3518                // If this is a new package in the process, add the package to the list
3519                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3520                checkTime(startTime, "startProcess: done, added package to proc");
3521                return app;
3522            }
3523
3524            // An application record is attached to a previous process,
3525            // clean it up now.
3526            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3527            checkTime(startTime, "startProcess: bad proc running, killing");
3528            killProcessGroup(app.uid, app.pid);
3529            handleAppDiedLocked(app, true, true);
3530            checkTime(startTime, "startProcess: done killing old proc");
3531        }
3532
3533        String hostingNameStr = hostingName != null
3534                ? hostingName.flattenToShortString() : null;
3535
3536        if (app == null) {
3537            checkTime(startTime, "startProcess: creating new process record");
3538            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3539            if (app == null) {
3540                Slog.w(TAG, "Failed making new process record for "
3541                        + processName + "/" + info.uid + " isolated=" + isolated);
3542                return null;
3543            }
3544            app.crashHandler = crashHandler;
3545            checkTime(startTime, "startProcess: done creating new process record");
3546        } else {
3547            // If this is a new package in the process, add the package to the list
3548            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3549            checkTime(startTime, "startProcess: added package to existing proc");
3550        }
3551
3552        // If the system is not ready yet, then hold off on starting this
3553        // process until it is.
3554        if (!mProcessesReady
3555                && !isAllowedWhileBooting(info)
3556                && !allowWhileBooting) {
3557            if (!mProcessesOnHold.contains(app)) {
3558                mProcessesOnHold.add(app);
3559            }
3560            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3561                    "System not ready, putting on hold: " + app);
3562            checkTime(startTime, "startProcess: returning with proc on hold");
3563            return app;
3564        }
3565
3566        checkTime(startTime, "startProcess: stepping in to startProcess");
3567        startProcessLocked(
3568                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3569        checkTime(startTime, "startProcess: done starting proc!");
3570        return (app.pid != 0) ? app : null;
3571    }
3572
3573    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3574        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3575    }
3576
3577    private final void startProcessLocked(ProcessRecord app,
3578            String hostingType, String hostingNameStr) {
3579        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3580                null /* entryPoint */, null /* entryPointArgs */);
3581    }
3582
3583    private final void startProcessLocked(ProcessRecord app, String hostingType,
3584            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3585        long startTime = SystemClock.elapsedRealtime();
3586        if (app.pid > 0 && app.pid != MY_PID) {
3587            checkTime(startTime, "startProcess: removing from pids map");
3588            synchronized (mPidsSelfLocked) {
3589                mPidsSelfLocked.remove(app.pid);
3590                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3591            }
3592            checkTime(startTime, "startProcess: done removing from pids map");
3593            app.setPid(0);
3594        }
3595
3596        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3597                "startProcessLocked removing on hold: " + app);
3598        mProcessesOnHold.remove(app);
3599
3600        checkTime(startTime, "startProcess: starting to update cpu stats");
3601        updateCpuStats();
3602        checkTime(startTime, "startProcess: done updating cpu stats");
3603
3604        try {
3605            try {
3606                final int userId = UserHandle.getUserId(app.uid);
3607                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3608            } catch (RemoteException e) {
3609                throw e.rethrowAsRuntimeException();
3610            }
3611
3612            int uid = app.uid;
3613            int[] gids = null;
3614            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3615            if (!app.isolated) {
3616                int[] permGids = null;
3617                try {
3618                    checkTime(startTime, "startProcess: getting gids from package manager");
3619                    final IPackageManager pm = AppGlobals.getPackageManager();
3620                    permGids = pm.getPackageGids(app.info.packageName,
3621                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3622                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3623                            MountServiceInternal.class);
3624                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3625                            app.info.packageName);
3626                } catch (RemoteException e) {
3627                    throw e.rethrowAsRuntimeException();
3628                }
3629
3630                /*
3631                 * Add shared application and profile GIDs so applications can share some
3632                 * resources like shared libraries and access user-wide resources
3633                 */
3634                if (ArrayUtils.isEmpty(permGids)) {
3635                    gids = new int[2];
3636                } else {
3637                    gids = new int[permGids.length + 2];
3638                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3639                }
3640                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3641                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3642            }
3643            checkTime(startTime, "startProcess: building args");
3644            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3645                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3646                        && mTopComponent != null
3647                        && app.processName.equals(mTopComponent.getPackageName())) {
3648                    uid = 0;
3649                }
3650                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3651                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3652                    uid = 0;
3653                }
3654            }
3655            int debugFlags = 0;
3656            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3658                // Also turn on CheckJNI for debuggable apps. It's quite
3659                // awkward to turn on otherwise.
3660                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3661            }
3662            // Run the app in safe mode if its manifest requests so or the
3663            // system is booted in safe mode.
3664            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3665                mSafeMode == true) {
3666                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3667            }
3668            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3669                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3670            }
3671            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3672            if ("true".equals(genDebugInfoProperty)) {
3673                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3674            }
3675            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3676                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3677            }
3678            if ("1".equals(SystemProperties.get("debug.assert"))) {
3679                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3680            }
3681            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3682                // Enable all debug flags required by the native debugger.
3683                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3684                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3685                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3686                mNativeDebuggingApp = null;
3687            }
3688
3689            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3690            if (requiredAbi == null) {
3691                requiredAbi = Build.SUPPORTED_ABIS[0];
3692            }
3693
3694            String instructionSet = null;
3695            if (app.info.primaryCpuAbi != null) {
3696                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3697            }
3698
3699            app.gids = gids;
3700            app.requiredAbi = requiredAbi;
3701            app.instructionSet = instructionSet;
3702
3703            // Start the process.  It will either succeed and return a result containing
3704            // the PID of the new process, or else throw a RuntimeException.
3705            boolean isActivityProcess = (entryPoint == null);
3706            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3707            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3708                    app.processName);
3709            checkTime(startTime, "startProcess: asking zygote to start proc");
3710            Process.ProcessStartResult startResult = Process.start(entryPoint,
3711                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3712                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3713                    app.info.dataDir, entryPointArgs);
3714            checkTime(startTime, "startProcess: returned from zygote!");
3715            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3716
3717            if (app.isolated) {
3718                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3719            }
3720            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3721            checkTime(startTime, "startProcess: done updating battery stats");
3722
3723            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3724                    UserHandle.getUserId(uid), startResult.pid, uid,
3725                    app.processName, hostingType,
3726                    hostingNameStr != null ? hostingNameStr : "");
3727
3728            try {
3729                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3730                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3731            } catch (RemoteException ex) {
3732                // Ignore
3733            }
3734
3735            if (app.persistent) {
3736                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3737            }
3738
3739            checkTime(startTime, "startProcess: building log message");
3740            StringBuilder buf = mStringBuilder;
3741            buf.setLength(0);
3742            buf.append("Start proc ");
3743            buf.append(startResult.pid);
3744            buf.append(':');
3745            buf.append(app.processName);
3746            buf.append('/');
3747            UserHandle.formatUid(buf, uid);
3748            if (!isActivityProcess) {
3749                buf.append(" [");
3750                buf.append(entryPoint);
3751                buf.append("]");
3752            }
3753            buf.append(" for ");
3754            buf.append(hostingType);
3755            if (hostingNameStr != null) {
3756                buf.append(" ");
3757                buf.append(hostingNameStr);
3758            }
3759            Slog.i(TAG, buf.toString());
3760            app.setPid(startResult.pid);
3761            app.usingWrapper = startResult.usingWrapper;
3762            app.removed = false;
3763            app.killed = false;
3764            app.killedByAm = false;
3765            checkTime(startTime, "startProcess: starting to update pids map");
3766            synchronized (mPidsSelfLocked) {
3767                this.mPidsSelfLocked.put(startResult.pid, app);
3768                if (isActivityProcess) {
3769                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3770                    msg.obj = app;
3771                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3772                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3773                }
3774            }
3775            checkTime(startTime, "startProcess: done updating pids map");
3776        } catch (RuntimeException e) {
3777            Slog.e(TAG, "Failure starting process " + app.processName, e);
3778
3779            // Something went very wrong while trying to start this process; one
3780            // common case is when the package is frozen due to an active
3781            // upgrade. To recover, clean up any active bookkeeping related to
3782            // starting this process. (We already invoked this method once when
3783            // the package was initially frozen through KILL_APPLICATION_MSG, so
3784            // it doesn't hurt to use it again.)
3785            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3786                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3787        }
3788    }
3789
3790    void updateUsageStats(ActivityRecord component, boolean resumed) {
3791        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3792                "updateUsageStats: comp=" + component + "res=" + resumed);
3793        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3794        if (resumed) {
3795            if (mUsageStatsService != null) {
3796                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3798            }
3799            synchronized (stats) {
3800                stats.noteActivityResumedLocked(component.app.uid);
3801            }
3802        } else {
3803            if (mUsageStatsService != null) {
3804                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3805                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3806            }
3807            synchronized (stats) {
3808                stats.noteActivityPausedLocked(component.app.uid);
3809            }
3810        }
3811    }
3812
3813    Intent getHomeIntent() {
3814        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3815        intent.setComponent(mTopComponent);
3816        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3817        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3818            intent.addCategory(Intent.CATEGORY_HOME);
3819        }
3820        return intent;
3821    }
3822
3823    boolean startHomeActivityLocked(int userId, String reason) {
3824        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3825                && mTopAction == null) {
3826            // We are running in factory test mode, but unable to find
3827            // the factory test app, so just sit around displaying the
3828            // error message and don't try to start anything.
3829            return false;
3830        }
3831        Intent intent = getHomeIntent();
3832        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3833        if (aInfo != null) {
3834            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3835            // Don't do this if the home app is currently being
3836            // instrumented.
3837            aInfo = new ActivityInfo(aInfo);
3838            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3839            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3840                    aInfo.applicationInfo.uid, true);
3841            if (app == null || app.instrumentationClass == null) {
3842                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3843                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3844            }
3845        } else {
3846            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3847        }
3848
3849        return true;
3850    }
3851
3852    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3853        ActivityInfo ai = null;
3854        ComponentName comp = intent.getComponent();
3855        try {
3856            if (comp != null) {
3857                // Factory test.
3858                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3859            } else {
3860                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3861                        intent,
3862                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3863                        flags, userId);
3864
3865                if (info != null) {
3866                    ai = info.activityInfo;
3867                }
3868            }
3869        } catch (RemoteException e) {
3870            // ignore
3871        }
3872
3873        return ai;
3874    }
3875
3876    /**
3877     * Starts the "new version setup screen" if appropriate.
3878     */
3879    void startSetupActivityLocked() {
3880        // Only do this once per boot.
3881        if (mCheckedForSetup) {
3882            return;
3883        }
3884
3885        // We will show this screen if the current one is a different
3886        // version than the last one shown, and we are not running in
3887        // low-level factory test mode.
3888        final ContentResolver resolver = mContext.getContentResolver();
3889        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3890                Settings.Global.getInt(resolver,
3891                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3892            mCheckedForSetup = true;
3893
3894            // See if we should be showing the platform update setup UI.
3895            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3896            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3897                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3898            if (!ris.isEmpty()) {
3899                final ResolveInfo ri = ris.get(0);
3900                String vers = ri.activityInfo.metaData != null
3901                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3902                        : null;
3903                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3904                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3905                            Intent.METADATA_SETUP_VERSION);
3906                }
3907                String lastVers = Settings.Secure.getString(
3908                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3909                if (vers != null && !vers.equals(lastVers)) {
3910                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3911                    intent.setComponent(new ComponentName(
3912                            ri.activityInfo.packageName, ri.activityInfo.name));
3913                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3914                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3915                            null, 0, 0, 0, null, false, false, null, null, null);
3916                }
3917            }
3918        }
3919    }
3920
3921    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3922        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3923    }
3924
3925    void enforceNotIsolatedCaller(String caller) {
3926        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3927            throw new SecurityException("Isolated process not allowed to call " + caller);
3928        }
3929    }
3930
3931    void enforceShellRestriction(String restriction, int userHandle) {
3932        if (Binder.getCallingUid() == Process.SHELL_UID) {
3933            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3934                throw new SecurityException("Shell does not have permission to access user "
3935                        + userHandle);
3936            }
3937        }
3938    }
3939
3940    @Override
3941    public int getFrontActivityScreenCompatMode() {
3942        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3943        synchronized (this) {
3944            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3945        }
3946    }
3947
3948    @Override
3949    public void setFrontActivityScreenCompatMode(int mode) {
3950        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3951                "setFrontActivityScreenCompatMode");
3952        synchronized (this) {
3953            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3954        }
3955    }
3956
3957    @Override
3958    public int getPackageScreenCompatMode(String packageName) {
3959        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3960        synchronized (this) {
3961            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3962        }
3963    }
3964
3965    @Override
3966    public void setPackageScreenCompatMode(String packageName, int mode) {
3967        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3968                "setPackageScreenCompatMode");
3969        synchronized (this) {
3970            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3971        }
3972    }
3973
3974    @Override
3975    public boolean getPackageAskScreenCompat(String packageName) {
3976        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3977        synchronized (this) {
3978            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3979        }
3980    }
3981
3982    @Override
3983    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3984        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3985                "setPackageAskScreenCompat");
3986        synchronized (this) {
3987            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3988        }
3989    }
3990
3991    private boolean hasUsageStatsPermission(String callingPackage) {
3992        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3993                Binder.getCallingUid(), callingPackage);
3994        if (mode == AppOpsManager.MODE_DEFAULT) {
3995            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3996                    == PackageManager.PERMISSION_GRANTED;
3997        }
3998        return mode == AppOpsManager.MODE_ALLOWED;
3999    }
4000
4001    @Override
4002    public int getPackageProcessState(String packageName, String callingPackage) {
4003        if (!hasUsageStatsPermission(callingPackage)) {
4004            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4005                    "getPackageProcessState");
4006        }
4007
4008        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4009        synchronized (this) {
4010            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4011                final ProcessRecord proc = mLruProcesses.get(i);
4012                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4013                        || procState > proc.setProcState) {
4014                    boolean found = false;
4015                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4016                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4017                            procState = proc.setProcState;
4018                            found = true;
4019                        }
4020                    }
4021                    if (proc.pkgDeps != null && !found) {
4022                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4023                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4024                                procState = proc.setProcState;
4025                                break;
4026                            }
4027                        }
4028                    }
4029                }
4030            }
4031        }
4032        return procState;
4033    }
4034
4035    @Override
4036    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4037        synchronized (this) {
4038            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4039            if (app == null) {
4040                return false;
4041            }
4042            if (app.trimMemoryLevel < level && app.thread != null &&
4043                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4044                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4045                try {
4046                    app.thread.scheduleTrimMemory(level);
4047                    app.trimMemoryLevel = level;
4048                    return true;
4049                } catch (RemoteException e) {
4050                    // Fallthrough to failure case.
4051                }
4052            }
4053        }
4054        return false;
4055    }
4056
4057    private void dispatchProcessesChanged() {
4058        int N;
4059        synchronized (this) {
4060            N = mPendingProcessChanges.size();
4061            if (mActiveProcessChanges.length < N) {
4062                mActiveProcessChanges = new ProcessChangeItem[N];
4063            }
4064            mPendingProcessChanges.toArray(mActiveProcessChanges);
4065            mPendingProcessChanges.clear();
4066            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4067                    "*** Delivering " + N + " process changes");
4068        }
4069
4070        int i = mProcessObservers.beginBroadcast();
4071        while (i > 0) {
4072            i--;
4073            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4074            if (observer != null) {
4075                try {
4076                    for (int j=0; j<N; j++) {
4077                        ProcessChangeItem item = mActiveProcessChanges[j];
4078                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4079                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4080                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4081                                    + item.uid + ": " + item.foregroundActivities);
4082                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4083                                    item.foregroundActivities);
4084                        }
4085                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4086                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4087                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4088                                    + ": " + item.processState);
4089                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4090                        }
4091                    }
4092                } catch (RemoteException e) {
4093                }
4094            }
4095        }
4096        mProcessObservers.finishBroadcast();
4097
4098        synchronized (this) {
4099            for (int j=0; j<N; j++) {
4100                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4101            }
4102        }
4103    }
4104
4105    private void dispatchProcessDied(int pid, int uid) {
4106        int i = mProcessObservers.beginBroadcast();
4107        while (i > 0) {
4108            i--;
4109            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4110            if (observer != null) {
4111                try {
4112                    observer.onProcessDied(pid, uid);
4113                } catch (RemoteException e) {
4114                }
4115            }
4116        }
4117        mProcessObservers.finishBroadcast();
4118    }
4119
4120    private void dispatchUidsChanged() {
4121        int N;
4122        synchronized (this) {
4123            N = mPendingUidChanges.size();
4124            if (mActiveUidChanges.length < N) {
4125                mActiveUidChanges = new UidRecord.ChangeItem[N];
4126            }
4127            for (int i=0; i<N; i++) {
4128                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4129                mActiveUidChanges[i] = change;
4130                if (change.uidRecord != null) {
4131                    change.uidRecord.pendingChange = null;
4132                    change.uidRecord = null;
4133                }
4134            }
4135            mPendingUidChanges.clear();
4136            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4137                    "*** Delivering " + N + " uid changes");
4138        }
4139
4140        if (mLocalPowerManager != null) {
4141            for (int j=0; j<N; j++) {
4142                UidRecord.ChangeItem item = mActiveUidChanges[j];
4143                if (item.change == UidRecord.CHANGE_GONE
4144                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4145                    mLocalPowerManager.uidGone(item.uid);
4146                } else {
4147                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4148                }
4149            }
4150        }
4151
4152        int i = mUidObservers.beginBroadcast();
4153        while (i > 0) {
4154            i--;
4155            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4156            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4157            if (observer != null) {
4158                try {
4159                    for (int j=0; j<N; j++) {
4160                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4161                        final int change = item.change;
4162                        UidRecord validateUid = null;
4163                        if (VALIDATE_UID_STATES && i == 0) {
4164                            validateUid = mValidateUids.get(item.uid);
4165                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4166                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4167                                validateUid = new UidRecord(item.uid);
4168                                mValidateUids.put(item.uid, validateUid);
4169                            }
4170                        }
4171                        if (change == UidRecord.CHANGE_IDLE
4172                                || change == UidRecord.CHANGE_GONE_IDLE) {
4173                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4174                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                                        "UID idle uid=" + item.uid);
4176                                observer.onUidIdle(item.uid);
4177                            }
4178                            if (VALIDATE_UID_STATES && i == 0) {
4179                                if (validateUid != null) {
4180                                    validateUid.idle = true;
4181                                }
4182                            }
4183                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4184                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4185                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186                                        "UID active uid=" + item.uid);
4187                                observer.onUidActive(item.uid);
4188                            }
4189                            if (VALIDATE_UID_STATES && i == 0) {
4190                                validateUid.idle = false;
4191                            }
4192                        }
4193                        if (change == UidRecord.CHANGE_GONE
4194                                || change == UidRecord.CHANGE_GONE_IDLE) {
4195                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4196                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                        "UID gone uid=" + item.uid);
4198                                observer.onUidGone(item.uid);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                if (validateUid != null) {
4202                                    mValidateUids.remove(item.uid);
4203                                }
4204                            }
4205                        } else {
4206                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID CHANGED uid=" + item.uid
4209                                                + ": " + item.processState);
4210                                observer.onUidStateChanged(item.uid, item.processState);
4211                            }
4212                            if (VALIDATE_UID_STATES && i == 0) {
4213                                validateUid.curProcState = validateUid.setProcState
4214                                        = item.processState;
4215                            }
4216                        }
4217                    }
4218                } catch (RemoteException e) {
4219                }
4220            }
4221        }
4222        mUidObservers.finishBroadcast();
4223
4224        synchronized (this) {
4225            for (int j=0; j<N; j++) {
4226                mAvailUidChanges.add(mActiveUidChanges[j]);
4227            }
4228        }
4229    }
4230
4231    @Override
4232    public final int startActivity(IApplicationThread caller, String callingPackage,
4233            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4234            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4235        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4236                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4237                UserHandle.getCallingUserId());
4238    }
4239
4240    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4241        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4242        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4243                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4244                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4245
4246        // TODO: Switch to user app stacks here.
4247        String mimeType = intent.getType();
4248        final Uri data = intent.getData();
4249        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4250            mimeType = getProviderMimeType(data, userId);
4251        }
4252        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4253
4254        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4255        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4256                null, 0, 0, null, null, null, null, false, userId, container, null);
4257    }
4258
4259    @Override
4260    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4261            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4262            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4263        enforceNotIsolatedCaller("startActivity");
4264        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4265                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4266        // TODO: Switch to user app stacks here.
4267        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4268                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4269                profilerInfo, null, null, bOptions, false, userId, null, null);
4270    }
4271
4272    @Override
4273    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4274            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4275            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4276            int userId) {
4277
4278        // This is very dangerous -- it allows you to perform a start activity (including
4279        // permission grants) as any app that may launch one of your own activities.  So
4280        // we will only allow this to be done from activities that are part of the core framework,
4281        // and then only when they are running as the system.
4282        final ActivityRecord sourceRecord;
4283        final int targetUid;
4284        final String targetPackage;
4285        synchronized (this) {
4286            if (resultTo == null) {
4287                throw new SecurityException("Must be called from an activity");
4288            }
4289            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4290            if (sourceRecord == null) {
4291                throw new SecurityException("Called with bad activity token: " + resultTo);
4292            }
4293            if (!sourceRecord.info.packageName.equals("android")) {
4294                throw new SecurityException(
4295                        "Must be called from an activity that is declared in the android package");
4296            }
4297            if (sourceRecord.app == null) {
4298                throw new SecurityException("Called without a process attached to activity");
4299            }
4300            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4301                // This is still okay, as long as this activity is running under the
4302                // uid of the original calling activity.
4303                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4304                    throw new SecurityException(
4305                            "Calling activity in uid " + sourceRecord.app.uid
4306                                    + " must be system uid or original calling uid "
4307                                    + sourceRecord.launchedFromUid);
4308                }
4309            }
4310            if (ignoreTargetSecurity) {
4311                if (intent.getComponent() == null) {
4312                    throw new SecurityException(
4313                            "Component must be specified with ignoreTargetSecurity");
4314                }
4315                if (intent.getSelector() != null) {
4316                    throw new SecurityException(
4317                            "Selector not allowed with ignoreTargetSecurity");
4318                }
4319            }
4320            targetUid = sourceRecord.launchedFromUid;
4321            targetPackage = sourceRecord.launchedFromPackage;
4322        }
4323
4324        if (userId == UserHandle.USER_NULL) {
4325            userId = UserHandle.getUserId(sourceRecord.app.uid);
4326        }
4327
4328        // TODO: Switch to user app stacks here.
4329        try {
4330            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4331                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4332                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4333            return ret;
4334        } catch (SecurityException e) {
4335            // XXX need to figure out how to propagate to original app.
4336            // A SecurityException here is generally actually a fault of the original
4337            // calling activity (such as a fairly granting permissions), so propagate it
4338            // back to them.
4339            /*
4340            StringBuilder msg = new StringBuilder();
4341            msg.append("While launching");
4342            msg.append(intent.toString());
4343            msg.append(": ");
4344            msg.append(e.getMessage());
4345            */
4346            throw e;
4347        }
4348    }
4349
4350    @Override
4351    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4352            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4353            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4354        enforceNotIsolatedCaller("startActivityAndWait");
4355        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4356                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4357        WaitResult res = new WaitResult();
4358        // TODO: Switch to user app stacks here.
4359        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4360                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4361                bOptions, false, userId, null, null);
4362        return res;
4363    }
4364
4365    @Override
4366    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4367            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4368            int startFlags, Configuration config, Bundle bOptions, int userId) {
4369        enforceNotIsolatedCaller("startActivityWithConfig");
4370        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4371                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4372        // TODO: Switch to user app stacks here.
4373        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4374                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4375                null, null, config, bOptions, false, userId, null, null);
4376        return ret;
4377    }
4378
4379    @Override
4380    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4381            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4382            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4383            throws TransactionTooLargeException {
4384        enforceNotIsolatedCaller("startActivityIntentSender");
4385        // Refuse possible leaked file descriptors
4386        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4387            throw new IllegalArgumentException("File descriptors passed in Intent");
4388        }
4389
4390        IIntentSender sender = intent.getTarget();
4391        if (!(sender instanceof PendingIntentRecord)) {
4392            throw new IllegalArgumentException("Bad PendingIntent object");
4393        }
4394
4395        PendingIntentRecord pir = (PendingIntentRecord)sender;
4396
4397        synchronized (this) {
4398            // If this is coming from the currently resumed activity, it is
4399            // effectively saying that app switches are allowed at this point.
4400            final ActivityStack stack = getFocusedStack();
4401            if (stack.mResumedActivity != null &&
4402                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4403                mAppSwitchesAllowedTime = 0;
4404            }
4405        }
4406        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4407                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4408        return ret;
4409    }
4410
4411    @Override
4412    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4413            Intent intent, String resolvedType, IVoiceInteractionSession session,
4414            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4415            Bundle bOptions, int userId) {
4416        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4417                != PackageManager.PERMISSION_GRANTED) {
4418            String msg = "Permission Denial: startVoiceActivity() from pid="
4419                    + Binder.getCallingPid()
4420                    + ", uid=" + Binder.getCallingUid()
4421                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4422            Slog.w(TAG, msg);
4423            throw new SecurityException(msg);
4424        }
4425        if (session == null || interactor == null) {
4426            throw new NullPointerException("null session or interactor");
4427        }
4428        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4429                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4430        // TODO: Switch to user app stacks here.
4431        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4432                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4433                null, bOptions, false, userId, null, null);
4434    }
4435
4436    @Override
4437    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4438            throws RemoteException {
4439        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4440        synchronized (this) {
4441            ActivityRecord activity = getFocusedStack().topActivity();
4442            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4443                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4444            }
4445            if (mRunningVoice != null || activity.task.voiceSession != null
4446                    || activity.voiceSession != null) {
4447                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4448                return;
4449            }
4450            if (activity.pendingVoiceInteractionStart) {
4451                Slog.w(TAG, "Pending start of voice interaction already.");
4452                return;
4453            }
4454            activity.pendingVoiceInteractionStart = true;
4455        }
4456        LocalServices.getService(VoiceInteractionManagerInternal.class)
4457                .startLocalVoiceInteraction(callingActivity, options);
4458    }
4459
4460    @Override
4461    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4462        LocalServices.getService(VoiceInteractionManagerInternal.class)
4463                .stopLocalVoiceInteraction(callingActivity);
4464    }
4465
4466    @Override
4467    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4468        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4469                .supportsLocalVoiceInteraction();
4470    }
4471
4472    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4473            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4474        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4475        if (activityToCallback == null) return;
4476        activityToCallback.setVoiceSessionLocked(voiceSession);
4477
4478        // Inform the activity
4479        try {
4480            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4481                    voiceInteractor);
4482            long token = Binder.clearCallingIdentity();
4483            try {
4484                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4485            } finally {
4486                Binder.restoreCallingIdentity(token);
4487            }
4488            // TODO: VI Should we cache the activity so that it's easier to find later
4489            // rather than scan through all the stacks and activities?
4490        } catch (RemoteException re) {
4491            activityToCallback.clearVoiceSessionLocked();
4492            // TODO: VI Should this terminate the voice session?
4493        }
4494    }
4495
4496    @Override
4497    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4498        synchronized (this) {
4499            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4500                if (keepAwake) {
4501                    mVoiceWakeLock.acquire();
4502                } else {
4503                    mVoiceWakeLock.release();
4504                }
4505            }
4506        }
4507    }
4508
4509    @Override
4510    public boolean startNextMatchingActivity(IBinder callingActivity,
4511            Intent intent, Bundle bOptions) {
4512        // Refuse possible leaked file descriptors
4513        if (intent != null && intent.hasFileDescriptors() == true) {
4514            throw new IllegalArgumentException("File descriptors passed in Intent");
4515        }
4516        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4517
4518        synchronized (this) {
4519            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4520            if (r == null) {
4521                ActivityOptions.abort(options);
4522                return false;
4523            }
4524            if (r.app == null || r.app.thread == null) {
4525                // The caller is not running...  d'oh!
4526                ActivityOptions.abort(options);
4527                return false;
4528            }
4529            intent = new Intent(intent);
4530            // The caller is not allowed to change the data.
4531            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4532            // And we are resetting to find the next component...
4533            intent.setComponent(null);
4534
4535            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4536
4537            ActivityInfo aInfo = null;
4538            try {
4539                List<ResolveInfo> resolves =
4540                    AppGlobals.getPackageManager().queryIntentActivities(
4541                            intent, r.resolvedType,
4542                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4543                            UserHandle.getCallingUserId()).getList();
4544
4545                // Look for the original activity in the list...
4546                final int N = resolves != null ? resolves.size() : 0;
4547                for (int i=0; i<N; i++) {
4548                    ResolveInfo rInfo = resolves.get(i);
4549                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4550                            && rInfo.activityInfo.name.equals(r.info.name)) {
4551                        // We found the current one...  the next matching is
4552                        // after it.
4553                        i++;
4554                        if (i<N) {
4555                            aInfo = resolves.get(i).activityInfo;
4556                        }
4557                        if (debug) {
4558                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4559                                    + "/" + r.info.name);
4560                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4561                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4562                        }
4563                        break;
4564                    }
4565                }
4566            } catch (RemoteException e) {
4567            }
4568
4569            if (aInfo == null) {
4570                // Nobody who is next!
4571                ActivityOptions.abort(options);
4572                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4573                return false;
4574            }
4575
4576            intent.setComponent(new ComponentName(
4577                    aInfo.applicationInfo.packageName, aInfo.name));
4578            intent.setFlags(intent.getFlags()&~(
4579                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4580                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4581                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4582                    Intent.FLAG_ACTIVITY_NEW_TASK));
4583
4584            // Okay now we need to start the new activity, replacing the
4585            // currently running activity.  This is a little tricky because
4586            // we want to start the new one as if the current one is finished,
4587            // but not finish the current one first so that there is no flicker.
4588            // And thus...
4589            final boolean wasFinishing = r.finishing;
4590            r.finishing = true;
4591
4592            // Propagate reply information over to the new activity.
4593            final ActivityRecord resultTo = r.resultTo;
4594            final String resultWho = r.resultWho;
4595            final int requestCode = r.requestCode;
4596            r.resultTo = null;
4597            if (resultTo != null) {
4598                resultTo.removeResultsLocked(r, resultWho, requestCode);
4599            }
4600
4601            final long origId = Binder.clearCallingIdentity();
4602            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4603                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4604                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4605                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4606                    false, false, null, null, null);
4607            Binder.restoreCallingIdentity(origId);
4608
4609            r.finishing = wasFinishing;
4610            if (res != ActivityManager.START_SUCCESS) {
4611                return false;
4612            }
4613            return true;
4614        }
4615    }
4616
4617    @Override
4618    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4619        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: startActivityFromRecents called without " +
4621                    START_TASKS_FROM_RECENTS;
4622            Slog.w(TAG, msg);
4623            throw new SecurityException(msg);
4624        }
4625        final long origId = Binder.clearCallingIdentity();
4626        try {
4627            synchronized (this) {
4628                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4629            }
4630        } finally {
4631            Binder.restoreCallingIdentity(origId);
4632        }
4633    }
4634
4635    final int startActivityInPackage(int uid, String callingPackage,
4636            Intent intent, String resolvedType, IBinder resultTo,
4637            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4638            IActivityContainer container, TaskRecord inTask) {
4639
4640        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4641                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4642
4643        // TODO: Switch to user app stacks here.
4644        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4645                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4646                null, null, null, bOptions, false, userId, container, inTask);
4647        return ret;
4648    }
4649
4650    @Override
4651    public final int startActivities(IApplicationThread caller, String callingPackage,
4652            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4653            int userId) {
4654        enforceNotIsolatedCaller("startActivities");
4655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4656                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4657        // TODO: Switch to user app stacks here.
4658        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4659                resolvedTypes, resultTo, bOptions, userId);
4660        return ret;
4661    }
4662
4663    final int startActivitiesInPackage(int uid, String callingPackage,
4664            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4665            Bundle bOptions, int userId) {
4666
4667        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4668                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4669        // TODO: Switch to user app stacks here.
4670        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4671                resultTo, bOptions, userId);
4672        return ret;
4673    }
4674
4675    @Override
4676    public void reportActivityFullyDrawn(IBinder token) {
4677        synchronized (this) {
4678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679            if (r == null) {
4680                return;
4681            }
4682            r.reportFullyDrawnLocked();
4683        }
4684    }
4685
4686    @Override
4687    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4688        synchronized (this) {
4689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4690            if (r == null) {
4691                return;
4692            }
4693            TaskRecord task = r.task;
4694            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4695                // Fixed screen orientation isn't supported when activities aren't in full screen
4696                // mode.
4697                return;
4698            }
4699            final long origId = Binder.clearCallingIdentity();
4700            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4701            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4702                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4703            if (config != null) {
4704                r.frozenBeforeDestroy = true;
4705                if (!updateConfigurationLocked(config, r, false)) {
4706                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4707                }
4708            }
4709            Binder.restoreCallingIdentity(origId);
4710        }
4711    }
4712
4713    @Override
4714    public int getRequestedOrientation(IBinder token) {
4715        synchronized (this) {
4716            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4717            if (r == null) {
4718                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4719            }
4720            return mWindowManager.getAppOrientation(r.appToken);
4721        }
4722    }
4723
4724    /**
4725     * This is the internal entry point for handling Activity.finish().
4726     *
4727     * @param token The Binder token referencing the Activity we want to finish.
4728     * @param resultCode Result code, if any, from this Activity.
4729     * @param resultData Result data (Intent), if any, from this Activity.
4730     * @param finishTask Whether to finish the task associated with this Activity.
4731     *
4732     * @return Returns true if the activity successfully finished, or false if it is still running.
4733     */
4734    @Override
4735    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4736            int finishTask) {
4737        // Refuse possible leaked file descriptors
4738        if (resultData != null && resultData.hasFileDescriptors() == true) {
4739            throw new IllegalArgumentException("File descriptors passed in Intent");
4740        }
4741
4742        synchronized(this) {
4743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4744            if (r == null) {
4745                return true;
4746            }
4747            // Keep track of the root activity of the task before we finish it
4748            TaskRecord tr = r.task;
4749            ActivityRecord rootR = tr.getRootActivity();
4750            if (rootR == null) {
4751                Slog.w(TAG, "Finishing task with all activities already finished");
4752            }
4753            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4754            // finish.
4755            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4756                    mStackSupervisor.isLastLockedTask(tr)) {
4757                Slog.i(TAG, "Not finishing task in lock task mode");
4758                mStackSupervisor.showLockTaskToast();
4759                return false;
4760            }
4761            if (mController != null) {
4762                // Find the first activity that is not finishing.
4763                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4764                if (next != null) {
4765                    // ask watcher if this is allowed
4766                    boolean resumeOK = true;
4767                    try {
4768                        resumeOK = mController.activityResuming(next.packageName);
4769                    } catch (RemoteException e) {
4770                        mController = null;
4771                        Watchdog.getInstance().setActivityController(null);
4772                    }
4773
4774                    if (!resumeOK) {
4775                        Slog.i(TAG, "Not finishing activity because controller resumed");
4776                        return false;
4777                    }
4778                }
4779            }
4780            final long origId = Binder.clearCallingIdentity();
4781            try {
4782                boolean res;
4783                final boolean finishWithRootActivity =
4784                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4785                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4786                        || (finishWithRootActivity && r == rootR)) {
4787                    // If requested, remove the task that is associated to this activity only if it
4788                    // was the root activity in the task. The result code and data is ignored
4789                    // because we don't support returning them across task boundaries. Also, to
4790                    // keep backwards compatibility we remove the task from recents when finishing
4791                    // task with root activity.
4792                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4793                    if (!res) {
4794                        Slog.i(TAG, "Removing task failed to finish activity");
4795                    }
4796                } else {
4797                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4798                            resultData, "app-request", true);
4799                    if (!res) {
4800                        Slog.i(TAG, "Failed to finish by app-request");
4801                    }
4802                }
4803                return res;
4804            } finally {
4805                Binder.restoreCallingIdentity(origId);
4806            }
4807        }
4808    }
4809
4810    @Override
4811    public final void finishHeavyWeightApp() {
4812        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4813                != PackageManager.PERMISSION_GRANTED) {
4814            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4815                    + Binder.getCallingPid()
4816                    + ", uid=" + Binder.getCallingUid()
4817                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4818            Slog.w(TAG, msg);
4819            throw new SecurityException(msg);
4820        }
4821
4822        synchronized(this) {
4823            if (mHeavyWeightProcess == null) {
4824                return;
4825            }
4826
4827            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4828            for (int i = 0; i < activities.size(); i++) {
4829                ActivityRecord r = activities.get(i);
4830                if (!r.finishing && r.isInStackLocked()) {
4831                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4832                            null, "finish-heavy", true);
4833                }
4834            }
4835
4836            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4837                    mHeavyWeightProcess.userId, 0));
4838            mHeavyWeightProcess = null;
4839        }
4840    }
4841
4842    @Override
4843    public void crashApplication(int uid, int initialPid, String packageName,
4844            String message) {
4845        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4846                != PackageManager.PERMISSION_GRANTED) {
4847            String msg = "Permission Denial: crashApplication() from pid="
4848                    + Binder.getCallingPid()
4849                    + ", uid=" + Binder.getCallingUid()
4850                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4851            Slog.w(TAG, msg);
4852            throw new SecurityException(msg);
4853        }
4854
4855        synchronized(this) {
4856            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4857        }
4858    }
4859
4860    @Override
4861    public final void finishSubActivity(IBinder token, String resultWho,
4862            int requestCode) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866            if (r != null) {
4867                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4868            }
4869            Binder.restoreCallingIdentity(origId);
4870        }
4871    }
4872
4873    @Override
4874    public boolean finishActivityAffinity(IBinder token) {
4875        synchronized(this) {
4876            final long origId = Binder.clearCallingIdentity();
4877            try {
4878                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4879                if (r == null) {
4880                    return false;
4881                }
4882
4883                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4884                // can finish.
4885                final TaskRecord task = r.task;
4886                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4887                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4888                    mStackSupervisor.showLockTaskToast();
4889                    return false;
4890                }
4891                return task.stack.finishActivityAffinityLocked(r);
4892            } finally {
4893                Binder.restoreCallingIdentity(origId);
4894            }
4895        }
4896    }
4897
4898    @Override
4899    public void finishVoiceTask(IVoiceInteractionSession session) {
4900        synchronized (this) {
4901            final long origId = Binder.clearCallingIdentity();
4902            try {
4903                // TODO: VI Consider treating local voice interactions and voice tasks
4904                // differently here
4905                mStackSupervisor.finishVoiceTask(session);
4906            } finally {
4907                Binder.restoreCallingIdentity(origId);
4908            }
4909        }
4910
4911    }
4912
4913    @Override
4914    public boolean releaseActivityInstance(IBinder token) {
4915        synchronized(this) {
4916            final long origId = Binder.clearCallingIdentity();
4917            try {
4918                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919                if (r == null) {
4920                    return false;
4921                }
4922                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4923            } finally {
4924                Binder.restoreCallingIdentity(origId);
4925            }
4926        }
4927    }
4928
4929    @Override
4930    public void releaseSomeActivities(IApplicationThread appInt) {
4931        synchronized(this) {
4932            final long origId = Binder.clearCallingIdentity();
4933            try {
4934                ProcessRecord app = getRecordForAppLocked(appInt);
4935                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4936            } finally {
4937                Binder.restoreCallingIdentity(origId);
4938            }
4939        }
4940    }
4941
4942    @Override
4943    public boolean willActivityBeVisible(IBinder token) {
4944        synchronized(this) {
4945            ActivityStack stack = ActivityRecord.getStackLocked(token);
4946            if (stack != null) {
4947                return stack.willActivityBeVisibleLocked(token);
4948            }
4949            return false;
4950        }
4951    }
4952
4953    @Override
4954    public void overridePendingTransition(IBinder token, String packageName,
4955            int enterAnim, int exitAnim) {
4956        synchronized(this) {
4957            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4958            if (self == null) {
4959                return;
4960            }
4961
4962            final long origId = Binder.clearCallingIdentity();
4963
4964            if (self.state == ActivityState.RESUMED
4965                    || self.state == ActivityState.PAUSING) {
4966                mWindowManager.overridePendingAppTransition(packageName,
4967                        enterAnim, exitAnim, null);
4968            }
4969
4970            Binder.restoreCallingIdentity(origId);
4971        }
4972    }
4973
4974    /**
4975     * Main function for removing an existing process from the activity manager
4976     * as a result of that process going away.  Clears out all connections
4977     * to the process.
4978     */
4979    private final void handleAppDiedLocked(ProcessRecord app,
4980            boolean restarting, boolean allowRestart) {
4981        int pid = app.pid;
4982        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4983        if (!kept && !restarting) {
4984            removeLruProcessLocked(app);
4985            if (pid > 0) {
4986                ProcessList.remove(pid);
4987            }
4988        }
4989
4990        if (mProfileProc == app) {
4991            clearProfilerLocked();
4992        }
4993
4994        // Remove this application's activities from active lists.
4995        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4996
4997        app.activities.clear();
4998
4999        if (app.instrumentationClass != null) {
5000            Slog.w(TAG, "Crash of app " + app.processName
5001                  + " running instrumentation " + app.instrumentationClass);
5002            Bundle info = new Bundle();
5003            info.putString("shortMsg", "Process crashed.");
5004            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5005        }
5006
5007        if (!restarting && hasVisibleActivities
5008                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5009            // If there was nothing to resume, and we are not already restarting this process, but
5010            // there is a visible activity that is hosted by the process...  then make sure all
5011            // visible activities are running, taking care of restarting this process.
5012            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5013        }
5014    }
5015
5016    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5017        IBinder threadBinder = thread.asBinder();
5018        // Find the application record.
5019        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5020            ProcessRecord rec = mLruProcesses.get(i);
5021            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5022                return i;
5023            }
5024        }
5025        return -1;
5026    }
5027
5028    final ProcessRecord getRecordForAppLocked(
5029            IApplicationThread thread) {
5030        if (thread == null) {
5031            return null;
5032        }
5033
5034        int appIndex = getLRURecordIndexForAppLocked(thread);
5035        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5036    }
5037
5038    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5039        // If there are no longer any background processes running,
5040        // and the app that died was not running instrumentation,
5041        // then tell everyone we are now low on memory.
5042        boolean haveBg = false;
5043        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5044            ProcessRecord rec = mLruProcesses.get(i);
5045            if (rec.thread != null
5046                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5047                haveBg = true;
5048                break;
5049            }
5050        }
5051
5052        if (!haveBg) {
5053            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5054            if (doReport) {
5055                long now = SystemClock.uptimeMillis();
5056                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5057                    doReport = false;
5058                } else {
5059                    mLastMemUsageReportTime = now;
5060                }
5061            }
5062            final ArrayList<ProcessMemInfo> memInfos
5063                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5064            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5065            long now = SystemClock.uptimeMillis();
5066            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5067                ProcessRecord rec = mLruProcesses.get(i);
5068                if (rec == dyingProc || rec.thread == null) {
5069                    continue;
5070                }
5071                if (doReport) {
5072                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5073                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5074                }
5075                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5076                    // The low memory report is overriding any current
5077                    // state for a GC request.  Make sure to do
5078                    // heavy/important/visible/foreground processes first.
5079                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5080                        rec.lastRequestedGc = 0;
5081                    } else {
5082                        rec.lastRequestedGc = rec.lastLowMemory;
5083                    }
5084                    rec.reportLowMemory = true;
5085                    rec.lastLowMemory = now;
5086                    mProcessesToGc.remove(rec);
5087                    addProcessToGcListLocked(rec);
5088                }
5089            }
5090            if (doReport) {
5091                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5092                mHandler.sendMessage(msg);
5093            }
5094            scheduleAppGcsLocked();
5095        }
5096    }
5097
5098    final void appDiedLocked(ProcessRecord app) {
5099       appDiedLocked(app, app.pid, app.thread, false);
5100    }
5101
5102    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5103            boolean fromBinderDied) {
5104        // First check if this ProcessRecord is actually active for the pid.
5105        synchronized (mPidsSelfLocked) {
5106            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5107            if (curProc != app) {
5108                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5109                return;
5110            }
5111        }
5112
5113        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5114        synchronized (stats) {
5115            stats.noteProcessDiedLocked(app.info.uid, pid);
5116        }
5117
5118        if (!app.killed) {
5119            if (!fromBinderDied) {
5120                Process.killProcessQuiet(pid);
5121            }
5122            killProcessGroup(app.uid, pid);
5123            app.killed = true;
5124        }
5125
5126        // Clean up already done if the process has been re-started.
5127        if (app.pid == pid && app.thread != null &&
5128                app.thread.asBinder() == thread.asBinder()) {
5129            boolean doLowMem = app.instrumentationClass == null;
5130            boolean doOomAdj = doLowMem;
5131            if (!app.killedByAm) {
5132                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5133                        + ") has died");
5134                mAllowLowerMemLevel = true;
5135            } else {
5136                // Note that we always want to do oom adj to update our state with the
5137                // new number of procs.
5138                mAllowLowerMemLevel = false;
5139                doLowMem = false;
5140            }
5141            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5142            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5143                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5144            handleAppDiedLocked(app, false, true);
5145
5146            if (doOomAdj) {
5147                updateOomAdjLocked();
5148            }
5149            if (doLowMem) {
5150                doLowMemReportIfNeededLocked(app);
5151            }
5152        } else if (app.pid != pid) {
5153            // A new process has already been started.
5154            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5155                    + ") has died and restarted (pid " + app.pid + ").");
5156            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5157        } else if (DEBUG_PROCESSES) {
5158            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5159                    + thread.asBinder());
5160        }
5161    }
5162
5163    /**
5164     * If a stack trace dump file is configured, dump process stack traces.
5165     * @param clearTraces causes the dump file to be erased prior to the new
5166     *    traces being written, if true; when false, the new traces will be
5167     *    appended to any existing file content.
5168     * @param firstPids of dalvik VM processes to dump stack traces for first
5169     * @param lastPids of dalvik VM processes to dump stack traces for last
5170     * @param nativeProcs optional list of native process names to dump stack crawls
5171     * @return file containing stack traces, or null if no dump file is configured
5172     */
5173    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5174            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5175        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5176        if (tracesPath == null || tracesPath.length() == 0) {
5177            return null;
5178        }
5179
5180        File tracesFile = new File(tracesPath);
5181        try {
5182            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5183            tracesFile.createNewFile();
5184            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5185        } catch (IOException e) {
5186            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5187            return null;
5188        }
5189
5190        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5191        return tracesFile;
5192    }
5193
5194    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5195            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5196        // Use a FileObserver to detect when traces finish writing.
5197        // The order of traces is considered important to maintain for legibility.
5198        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5199            @Override
5200            public synchronized void onEvent(int event, String path) { notify(); }
5201        };
5202
5203        try {
5204            observer.startWatching();
5205
5206            // First collect all of the stacks of the most important pids.
5207            if (firstPids != null) {
5208                try {
5209                    int num = firstPids.size();
5210                    for (int i = 0; i < num; i++) {
5211                        synchronized (observer) {
5212                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5213                                    + firstPids.get(i));
5214                            final long sime = SystemClock.elapsedRealtime();
5215                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5216                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5217                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5218                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5219                        }
5220                    }
5221                } catch (InterruptedException e) {
5222                    Slog.wtf(TAG, e);
5223                }
5224            }
5225
5226            // Next collect the stacks of the native pids
5227            if (nativeProcs != null) {
5228                int[] pids = Process.getPidsForCommands(nativeProcs);
5229                if (pids != null) {
5230                    for (int pid : pids) {
5231                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5232                        final long sime = SystemClock.elapsedRealtime();
5233                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5234                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5235                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5236                    }
5237                }
5238            }
5239
5240            // Lastly, measure CPU usage.
5241            if (processCpuTracker != null) {
5242                processCpuTracker.init();
5243                System.gc();
5244                processCpuTracker.update();
5245                try {
5246                    synchronized (processCpuTracker) {
5247                        processCpuTracker.wait(500); // measure over 1/2 second.
5248                    }
5249                } catch (InterruptedException e) {
5250                }
5251                processCpuTracker.update();
5252
5253                // We'll take the stack crawls of just the top apps using CPU.
5254                final int N = processCpuTracker.countWorkingStats();
5255                int numProcs = 0;
5256                for (int i=0; i<N && numProcs<5; i++) {
5257                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5258                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5259                        numProcs++;
5260                        try {
5261                            synchronized (observer) {
5262                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5263                                        + stats.pid);
5264                                final long stime = SystemClock.elapsedRealtime();
5265                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5266                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5267                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5268                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5269                            }
5270                        } catch (InterruptedException e) {
5271                            Slog.wtf(TAG, e);
5272                        }
5273                    } else if (DEBUG_ANR) {
5274                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5275                                + stats.pid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            observer.stopWatching();
5281        }
5282    }
5283
5284    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5285        if (true || IS_USER_BUILD) {
5286            return;
5287        }
5288        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5289        if (tracesPath == null || tracesPath.length() == 0) {
5290            return;
5291        }
5292
5293        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5294        StrictMode.allowThreadDiskWrites();
5295        try {
5296            final File tracesFile = new File(tracesPath);
5297            final File tracesDir = tracesFile.getParentFile();
5298            final File tracesTmp = new File(tracesDir, "__tmp__");
5299            try {
5300                if (tracesFile.exists()) {
5301                    tracesTmp.delete();
5302                    tracesFile.renameTo(tracesTmp);
5303                }
5304                StringBuilder sb = new StringBuilder();
5305                Time tobj = new Time();
5306                tobj.set(System.currentTimeMillis());
5307                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5308                sb.append(": ");
5309                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5310                sb.append(" since ");
5311                sb.append(msg);
5312                FileOutputStream fos = new FileOutputStream(tracesFile);
5313                fos.write(sb.toString().getBytes());
5314                if (app == null) {
5315                    fos.write("\n*** No application process!".getBytes());
5316                }
5317                fos.close();
5318                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5319            } catch (IOException e) {
5320                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5321                return;
5322            }
5323
5324            if (app != null) {
5325                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5326                firstPids.add(app.pid);
5327                dumpStackTraces(tracesPath, firstPids, null, null, null);
5328            }
5329
5330            File lastTracesFile = null;
5331            File curTracesFile = null;
5332            for (int i=9; i>=0; i--) {
5333                String name = String.format(Locale.US, "slow%02d.txt", i);
5334                curTracesFile = new File(tracesDir, name);
5335                if (curTracesFile.exists()) {
5336                    if (lastTracesFile != null) {
5337                        curTracesFile.renameTo(lastTracesFile);
5338                    } else {
5339                        curTracesFile.delete();
5340                    }
5341                }
5342                lastTracesFile = curTracesFile;
5343            }
5344            tracesFile.renameTo(curTracesFile);
5345            if (tracesTmp.exists()) {
5346                tracesTmp.renameTo(tracesFile);
5347            }
5348        } finally {
5349            StrictMode.setThreadPolicy(oldPolicy);
5350        }
5351    }
5352
5353    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5354        if (!mLaunchWarningShown) {
5355            mLaunchWarningShown = true;
5356            mUiHandler.post(new Runnable() {
5357                @Override
5358                public void run() {
5359                    synchronized (ActivityManagerService.this) {
5360                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5361                        d.show();
5362                        mUiHandler.postDelayed(new Runnable() {
5363                            @Override
5364                            public void run() {
5365                                synchronized (ActivityManagerService.this) {
5366                                    d.dismiss();
5367                                    mLaunchWarningShown = false;
5368                                }
5369                            }
5370                        }, 4000);
5371                    }
5372                }
5373            });
5374        }
5375    }
5376
5377    @Override
5378    public boolean clearApplicationUserData(final String packageName,
5379            final IPackageDataObserver observer, int userId) {
5380        enforceNotIsolatedCaller("clearApplicationUserData");
5381        int uid = Binder.getCallingUid();
5382        int pid = Binder.getCallingPid();
5383        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5384                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5385
5386
5387        long callingId = Binder.clearCallingIdentity();
5388        try {
5389            IPackageManager pm = AppGlobals.getPackageManager();
5390            int pkgUid = -1;
5391            synchronized(this) {
5392                if (getPackageManagerInternalLocked().canPackageBeWiped(
5393                        userId, packageName)) {
5394                    throw new SecurityException(
5395                            "Cannot clear data for a device owner or a profile owner");
5396                }
5397
5398                try {
5399                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5400                } catch (RemoteException e) {
5401                }
5402                if (pkgUid == -1) {
5403                    Slog.w(TAG, "Invalid packageName: " + packageName);
5404                    if (observer != null) {
5405                        try {
5406                            observer.onRemoveCompleted(packageName, false);
5407                        } catch (RemoteException e) {
5408                            Slog.i(TAG, "Observer no longer exists.");
5409                        }
5410                    }
5411                    return false;
5412                }
5413                if (uid == pkgUid || checkComponentPermission(
5414                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5415                        pid, uid, -1, true)
5416                        == PackageManager.PERMISSION_GRANTED) {
5417                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5418                } else {
5419                    throw new SecurityException("PID " + pid + " does not have permission "
5420                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5421                                    + " of package " + packageName);
5422                }
5423
5424                // Remove all tasks match the cleared application package and user
5425                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5426                    final TaskRecord tr = mRecentTasks.get(i);
5427                    final String taskPackageName =
5428                            tr.getBaseIntent().getComponent().getPackageName();
5429                    if (tr.userId != userId) continue;
5430                    if (!taskPackageName.equals(packageName)) continue;
5431                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5432                }
5433            }
5434
5435            final int pkgUidF = pkgUid;
5436            final int userIdF = userId;
5437            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5438                @Override
5439                public void onRemoveCompleted(String packageName, boolean succeeded)
5440                        throws RemoteException {
5441                    synchronized (ActivityManagerService.this) {
5442                        finishForceStopPackageLocked(packageName, pkgUidF);
5443                    }
5444
5445                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5446                            Uri.fromParts("package", packageName, null));
5447                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5448                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5449                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5450                            null, null, 0, null, null, null, null, false, false, userIdF);
5451
5452                    if (observer != null) {
5453                        observer.onRemoveCompleted(packageName, succeeded);
5454                    }
5455                }
5456            };
5457
5458            try {
5459                // Clear application user data
5460                pm.clearApplicationUserData(packageName, localObserver, userId);
5461
5462                synchronized(this) {
5463                    // Remove all permissions granted from/to this package
5464                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5465                }
5466
5467                // Remove all zen rules created by this package; revoke it's zen access.
5468                INotificationManager inm = NotificationManager.getService();
5469                inm.removeAutomaticZenRules(packageName);
5470                inm.setNotificationPolicyAccessGranted(packageName, false);
5471
5472            } catch (RemoteException e) {
5473            }
5474        } finally {
5475            Binder.restoreCallingIdentity(callingId);
5476        }
5477        return true;
5478    }
5479
5480    @Override
5481    public void killBackgroundProcesses(final String packageName, int userId) {
5482        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5483                != PackageManager.PERMISSION_GRANTED &&
5484                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5485                        != PackageManager.PERMISSION_GRANTED) {
5486            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5487                    + Binder.getCallingPid()
5488                    + ", uid=" + Binder.getCallingUid()
5489                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5490            Slog.w(TAG, msg);
5491            throw new SecurityException(msg);
5492        }
5493
5494        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5495                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5496        long callingId = Binder.clearCallingIdentity();
5497        try {
5498            IPackageManager pm = AppGlobals.getPackageManager();
5499            synchronized(this) {
5500                int appId = -1;
5501                try {
5502                    appId = UserHandle.getAppId(
5503                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5504                } catch (RemoteException e) {
5505                }
5506                if (appId == -1) {
5507                    Slog.w(TAG, "Invalid packageName: " + packageName);
5508                    return;
5509                }
5510                killPackageProcessesLocked(packageName, appId, userId,
5511                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5512            }
5513        } finally {
5514            Binder.restoreCallingIdentity(callingId);
5515        }
5516    }
5517
5518    @Override
5519    public void killAllBackgroundProcesses() {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5523                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5524                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5525            Slog.w(TAG, msg);
5526            throw new SecurityException(msg);
5527        }
5528
5529        final long callingId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5533                final int NP = mProcessNames.getMap().size();
5534                for (int ip = 0; ip < NP; ip++) {
5535                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536                    final int NA = apps.size();
5537                    for (int ia = 0; ia < NA; ia++) {
5538                        final ProcessRecord app = apps.valueAt(ia);
5539                        if (app.persistent) {
5540                            // We don't kill persistent processes.
5541                            continue;
5542                        }
5543                        if (app.removed) {
5544                            procs.add(app);
5545                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5546                            app.removed = true;
5547                            procs.add(app);
5548                        }
5549                    }
5550                }
5551
5552                final int N = procs.size();
5553                for (int i = 0; i < N; i++) {
5554                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5555                }
5556
5557                mAllowLowerMemLevel = true;
5558
5559                updateOomAdjLocked();
5560                doLowMemReportIfNeededLocked(null);
5561            }
5562        } finally {
5563            Binder.restoreCallingIdentity(callingId);
5564        }
5565    }
5566
5567    /**
5568     * Kills all background processes, except those matching any of the
5569     * specified properties.
5570     *
5571     * @param minTargetSdk the target SDK version at or above which to preserve
5572     *                     processes, or {@code -1} to ignore the target SDK
5573     * @param maxProcState the process state at or below which to preserve
5574     *                     processes, or {@code -1} to ignore the process state
5575     */
5576    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5577        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5578                != PackageManager.PERMISSION_GRANTED) {
5579            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5580                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5581                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5582            Slog.w(TAG, msg);
5583            throw new SecurityException(msg);
5584        }
5585
5586        final long callingId = Binder.clearCallingIdentity();
5587        try {
5588            synchronized (this) {
5589                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5590                final int NP = mProcessNames.getMap().size();
5591                for (int ip = 0; ip < NP; ip++) {
5592                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5593                    final int NA = apps.size();
5594                    for (int ia = 0; ia < NA; ia++) {
5595                        final ProcessRecord app = apps.valueAt(ia);
5596                        if (app.removed) {
5597                            procs.add(app);
5598                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5599                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5600                            app.removed = true;
5601                            procs.add(app);
5602                        }
5603                    }
5604                }
5605
5606                final int N = procs.size();
5607                for (int i = 0; i < N; i++) {
5608                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5609                }
5610            }
5611        } finally {
5612            Binder.restoreCallingIdentity(callingId);
5613        }
5614    }
5615
5616    @Override
5617    public void forceStopPackage(final String packageName, int userId) {
5618        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5619                != PackageManager.PERMISSION_GRANTED) {
5620            String msg = "Permission Denial: forceStopPackage() from pid="
5621                    + Binder.getCallingPid()
5622                    + ", uid=" + Binder.getCallingUid()
5623                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5624            Slog.w(TAG, msg);
5625            throw new SecurityException(msg);
5626        }
5627        final int callingPid = Binder.getCallingPid();
5628        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5629                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5630        long callingId = Binder.clearCallingIdentity();
5631        try {
5632            IPackageManager pm = AppGlobals.getPackageManager();
5633            synchronized(this) {
5634                int[] users = userId == UserHandle.USER_ALL
5635                        ? mUserController.getUsers() : new int[] { userId };
5636                for (int user : users) {
5637                    int pkgUid = -1;
5638                    try {
5639                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5640                                user);
5641                    } catch (RemoteException e) {
5642                    }
5643                    if (pkgUid == -1) {
5644                        Slog.w(TAG, "Invalid packageName: " + packageName);
5645                        continue;
5646                    }
5647                    try {
5648                        pm.setPackageStoppedState(packageName, true, user);
5649                    } catch (RemoteException e) {
5650                    } catch (IllegalArgumentException e) {
5651                        Slog.w(TAG, "Failed trying to unstop package "
5652                                + packageName + ": " + e);
5653                    }
5654                    if (mUserController.isUserRunningLocked(user, 0)) {
5655                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5656                        finishForceStopPackageLocked(packageName, pkgUid);
5657                    }
5658                }
5659            }
5660        } finally {
5661            Binder.restoreCallingIdentity(callingId);
5662        }
5663    }
5664
5665    @Override
5666    public void addPackageDependency(String packageName) {
5667        synchronized (this) {
5668            int callingPid = Binder.getCallingPid();
5669            if (callingPid == Process.myPid()) {
5670                //  Yeah, um, no.
5671                return;
5672            }
5673            ProcessRecord proc;
5674            synchronized (mPidsSelfLocked) {
5675                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5676            }
5677            if (proc != null) {
5678                if (proc.pkgDeps == null) {
5679                    proc.pkgDeps = new ArraySet<String>(1);
5680                }
5681                proc.pkgDeps.add(packageName);
5682            }
5683        }
5684    }
5685
5686    /*
5687     * The pkg name and app id have to be specified.
5688     */
5689    @Override
5690    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5691        if (pkg == null) {
5692            return;
5693        }
5694        // Make sure the uid is valid.
5695        if (appid < 0) {
5696            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5697            return;
5698        }
5699        int callerUid = Binder.getCallingUid();
5700        // Only the system server can kill an application
5701        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5702            // Post an aysnc message to kill the application
5703            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5704            msg.arg1 = appid;
5705            msg.arg2 = 0;
5706            Bundle bundle = new Bundle();
5707            bundle.putString("pkg", pkg);
5708            bundle.putString("reason", reason);
5709            msg.obj = bundle;
5710            mHandler.sendMessage(msg);
5711        } else {
5712            throw new SecurityException(callerUid + " cannot kill pkg: " +
5713                    pkg);
5714        }
5715    }
5716
5717    @Override
5718    public void closeSystemDialogs(String reason) {
5719        enforceNotIsolatedCaller("closeSystemDialogs");
5720
5721        final int pid = Binder.getCallingPid();
5722        final int uid = Binder.getCallingUid();
5723        final long origId = Binder.clearCallingIdentity();
5724        try {
5725            synchronized (this) {
5726                // Only allow this from foreground processes, so that background
5727                // applications can't abuse it to prevent system UI from being shown.
5728                if (uid >= Process.FIRST_APPLICATION_UID) {
5729                    ProcessRecord proc;
5730                    synchronized (mPidsSelfLocked) {
5731                        proc = mPidsSelfLocked.get(pid);
5732                    }
5733                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5734                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5735                                + " from background process " + proc);
5736                        return;
5737                    }
5738                }
5739                closeSystemDialogsLocked(reason);
5740            }
5741        } finally {
5742            Binder.restoreCallingIdentity(origId);
5743        }
5744    }
5745
5746    void closeSystemDialogsLocked(String reason) {
5747        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5748        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5749                | Intent.FLAG_RECEIVER_FOREGROUND);
5750        if (reason != null) {
5751            intent.putExtra("reason", reason);
5752        }
5753        mWindowManager.closeSystemDialogs(reason);
5754
5755        mStackSupervisor.closeSystemDialogsLocked();
5756
5757        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5758                AppOpsManager.OP_NONE, null, false, false,
5759                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5760    }
5761
5762    @Override
5763    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5764        enforceNotIsolatedCaller("getProcessMemoryInfo");
5765        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5766        for (int i=pids.length-1; i>=0; i--) {
5767            ProcessRecord proc;
5768            int oomAdj;
5769            synchronized (this) {
5770                synchronized (mPidsSelfLocked) {
5771                    proc = mPidsSelfLocked.get(pids[i]);
5772                    oomAdj = proc != null ? proc.setAdj : 0;
5773                }
5774            }
5775            infos[i] = new Debug.MemoryInfo();
5776            Debug.getMemoryInfo(pids[i], infos[i]);
5777            if (proc != null) {
5778                synchronized (this) {
5779                    if (proc.thread != null && proc.setAdj == oomAdj) {
5780                        // Record this for posterity if the process has been stable.
5781                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5782                                infos[i].getTotalUss(), false, proc.pkgList);
5783                    }
5784                }
5785            }
5786        }
5787        return infos;
5788    }
5789
5790    @Override
5791    public long[] getProcessPss(int[] pids) {
5792        enforceNotIsolatedCaller("getProcessPss");
5793        long[] pss = new long[pids.length];
5794        for (int i=pids.length-1; i>=0; i--) {
5795            ProcessRecord proc;
5796            int oomAdj;
5797            synchronized (this) {
5798                synchronized (mPidsSelfLocked) {
5799                    proc = mPidsSelfLocked.get(pids[i]);
5800                    oomAdj = proc != null ? proc.setAdj : 0;
5801                }
5802            }
5803            long[] tmpUss = new long[1];
5804            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5805            if (proc != null) {
5806                synchronized (this) {
5807                    if (proc.thread != null && proc.setAdj == oomAdj) {
5808                        // Record this for posterity if the process has been stable.
5809                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5810                    }
5811                }
5812            }
5813        }
5814        return pss;
5815    }
5816
5817    @Override
5818    public void killApplicationProcess(String processName, int uid) {
5819        if (processName == null) {
5820            return;
5821        }
5822
5823        int callerUid = Binder.getCallingUid();
5824        // Only the system server can kill an application
5825        if (callerUid == Process.SYSTEM_UID) {
5826            synchronized (this) {
5827                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5828                if (app != null && app.thread != null) {
5829                    try {
5830                        app.thread.scheduleSuicide();
5831                    } catch (RemoteException e) {
5832                        // If the other end already died, then our work here is done.
5833                    }
5834                } else {
5835                    Slog.w(TAG, "Process/uid not found attempting kill of "
5836                            + processName + " / " + uid);
5837                }
5838            }
5839        } else {
5840            throw new SecurityException(callerUid + " cannot kill app process: " +
5841                    processName);
5842        }
5843    }
5844
5845    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5846        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5847                false, true, false, false, UserHandle.getUserId(uid), reason);
5848    }
5849
5850    private void finishForceStopPackageLocked(final String packageName, int uid) {
5851        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5852                Uri.fromParts("package", packageName, null));
5853        if (!mProcessesReady) {
5854            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855                    | Intent.FLAG_RECEIVER_FOREGROUND);
5856        }
5857        intent.putExtra(Intent.EXTRA_UID, uid);
5858        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5859        broadcastIntentLocked(null, null, intent,
5860                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5861                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5862    }
5863
5864
5865    private final boolean killPackageProcessesLocked(String packageName, int appId,
5866            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5867            boolean doit, boolean evenPersistent, String reason) {
5868        ArrayList<ProcessRecord> procs = new ArrayList<>();
5869
5870        // Remove all processes this package may have touched: all with the
5871        // same UID (except for the system or root user), and all whose name
5872        // matches the package name.
5873        final int NP = mProcessNames.getMap().size();
5874        for (int ip=0; ip<NP; ip++) {
5875            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5876            final int NA = apps.size();
5877            for (int ia=0; ia<NA; ia++) {
5878                ProcessRecord app = apps.valueAt(ia);
5879                if (app.persistent && !evenPersistent) {
5880                    // we don't kill persistent processes
5881                    continue;
5882                }
5883                if (app.removed) {
5884                    if (doit) {
5885                        procs.add(app);
5886                    }
5887                    continue;
5888                }
5889
5890                // Skip process if it doesn't meet our oom adj requirement.
5891                if (app.setAdj < minOomAdj) {
5892                    continue;
5893                }
5894
5895                // If no package is specified, we call all processes under the
5896                // give user id.
5897                if (packageName == null) {
5898                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5899                        continue;
5900                    }
5901                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5902                        continue;
5903                    }
5904                // Package has been specified, we want to hit all processes
5905                // that match it.  We need to qualify this by the processes
5906                // that are running under the specified app and user ID.
5907                } else {
5908                    final boolean isDep = app.pkgDeps != null
5909                            && app.pkgDeps.contains(packageName);
5910                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5911                        continue;
5912                    }
5913                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5914                        continue;
5915                    }
5916                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5917                        continue;
5918                    }
5919                }
5920
5921                // Process has passed all conditions, kill it!
5922                if (!doit) {
5923                    return true;
5924                }
5925                app.removed = true;
5926                procs.add(app);
5927            }
5928        }
5929
5930        int N = procs.size();
5931        for (int i=0; i<N; i++) {
5932            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5933        }
5934        updateOomAdjLocked();
5935        return N > 0;
5936    }
5937
5938    private void cleanupDisabledPackageComponentsLocked(
5939            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5940
5941        Set<String> disabledClasses = null;
5942        boolean packageDisabled = false;
5943        IPackageManager pm = AppGlobals.getPackageManager();
5944
5945        if (changedClasses == null) {
5946            // Nothing changed...
5947            return;
5948        }
5949
5950        // Determine enable/disable state of the package and its components.
5951        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5952        for (int i = changedClasses.length - 1; i >= 0; i--) {
5953            final String changedClass = changedClasses[i];
5954
5955            if (changedClass.equals(packageName)) {
5956                try {
5957                    // Entire package setting changed
5958                    enabled = pm.getApplicationEnabledSetting(packageName,
5959                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5960                } catch (Exception e) {
5961                    // No such package/component; probably racing with uninstall.  In any
5962                    // event it means we have nothing further to do here.
5963                    return;
5964                }
5965                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5966                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5967                if (packageDisabled) {
5968                    // Entire package is disabled.
5969                    // No need to continue to check component states.
5970                    disabledClasses = null;
5971                    break;
5972                }
5973            } else {
5974                try {
5975                    enabled = pm.getComponentEnabledSetting(
5976                            new ComponentName(packageName, changedClass),
5977                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5978                } catch (Exception e) {
5979                    // As above, probably racing with uninstall.
5980                    return;
5981                }
5982                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5983                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5984                    if (disabledClasses == null) {
5985                        disabledClasses = new ArraySet<>(changedClasses.length);
5986                    }
5987                    disabledClasses.add(changedClass);
5988                }
5989            }
5990        }
5991
5992        if (!packageDisabled && disabledClasses == null) {
5993            // Nothing to do here...
5994            return;
5995        }
5996
5997        // Clean-up disabled activities.
5998        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5999                packageName, disabledClasses, true, false, userId) && mBooted) {
6000            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6001            mStackSupervisor.scheduleIdleLocked();
6002        }
6003
6004        // Clean-up disabled tasks
6005        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6006
6007        // Clean-up disabled services.
6008        mServices.bringDownDisabledPackageServicesLocked(
6009                packageName, disabledClasses, userId, false, killProcess, true);
6010
6011        // Clean-up disabled providers.
6012        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6013        mProviderMap.collectPackageProvidersLocked(
6014                packageName, disabledClasses, true, false, userId, providers);
6015        for (int i = providers.size() - 1; i >= 0; i--) {
6016            removeDyingProviderLocked(null, providers.get(i), true);
6017        }
6018
6019        // Clean-up disabled broadcast receivers.
6020        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                    packageName, disabledClasses, userId, true);
6023        }
6024
6025    }
6026
6027    final boolean clearBroadcastQueueForUserLocked(int userId) {
6028        boolean didSomething = false;
6029        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6030            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6031                    null, null, userId, true);
6032        }
6033        return didSomething;
6034    }
6035
6036    final boolean forceStopPackageLocked(String packageName, int appId,
6037            boolean callerWillRestart, boolean purgeCache, boolean doit,
6038            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6039        int i;
6040
6041        if (userId == UserHandle.USER_ALL && packageName == null) {
6042            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6043        }
6044
6045        if (appId < 0 && packageName != null) {
6046            try {
6047                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6048                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6049            } catch (RemoteException e) {
6050            }
6051        }
6052
6053        if (doit) {
6054            if (packageName != null) {
6055                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6056                        + " user=" + userId + ": " + reason);
6057            } else {
6058                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6059            }
6060
6061            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6062        }
6063
6064        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6065                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6066                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6067
6068        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6069                packageName, null, doit, evenPersistent, userId)) {
6070            if (!doit) {
6071                return true;
6072            }
6073            didSomething = true;
6074        }
6075
6076        if (mServices.bringDownDisabledPackageServicesLocked(
6077                packageName, null, userId, evenPersistent, true, doit)) {
6078            if (!doit) {
6079                return true;
6080            }
6081            didSomething = true;
6082        }
6083
6084        if (packageName == null) {
6085            // Remove all sticky broadcasts from this user.
6086            mStickyBroadcasts.remove(userId);
6087        }
6088
6089        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6090        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6091                userId, providers)) {
6092            if (!doit) {
6093                return true;
6094            }
6095            didSomething = true;
6096        }
6097        for (i = providers.size() - 1; i >= 0; i--) {
6098            removeDyingProviderLocked(null, providers.get(i), true);
6099        }
6100
6101        // Remove transient permissions granted from/to this package/user
6102        removeUriPermissionsForPackageLocked(packageName, userId, false);
6103
6104        if (doit) {
6105            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6106                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6107                        packageName, null, userId, doit);
6108            }
6109        }
6110
6111        if (packageName == null || uninstalling) {
6112            // Remove pending intents.  For now we only do this when force
6113            // stopping users, because we have some problems when doing this
6114            // for packages -- app widgets are not currently cleaned up for
6115            // such packages, so they can be left with bad pending intents.
6116            if (mIntentSenderRecords.size() > 0) {
6117                Iterator<WeakReference<PendingIntentRecord>> it
6118                        = mIntentSenderRecords.values().iterator();
6119                while (it.hasNext()) {
6120                    WeakReference<PendingIntentRecord> wpir = it.next();
6121                    if (wpir == null) {
6122                        it.remove();
6123                        continue;
6124                    }
6125                    PendingIntentRecord pir = wpir.get();
6126                    if (pir == null) {
6127                        it.remove();
6128                        continue;
6129                    }
6130                    if (packageName == null) {
6131                        // Stopping user, remove all objects for the user.
6132                        if (pir.key.userId != userId) {
6133                            // Not the same user, skip it.
6134                            continue;
6135                        }
6136                    } else {
6137                        if (UserHandle.getAppId(pir.uid) != appId) {
6138                            // Different app id, skip it.
6139                            continue;
6140                        }
6141                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6142                            // Different user, skip it.
6143                            continue;
6144                        }
6145                        if (!pir.key.packageName.equals(packageName)) {
6146                            // Different package, skip it.
6147                            continue;
6148                        }
6149                    }
6150                    if (!doit) {
6151                        return true;
6152                    }
6153                    didSomething = true;
6154                    it.remove();
6155                    pir.canceled = true;
6156                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6157                        pir.key.activity.pendingResults.remove(pir.ref);
6158                    }
6159                }
6160            }
6161        }
6162
6163        if (doit) {
6164            if (purgeCache && packageName != null) {
6165                AttributeCache ac = AttributeCache.instance();
6166                if (ac != null) {
6167                    ac.removePackage(packageName);
6168                }
6169            }
6170            if (mBooted) {
6171                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6172                mStackSupervisor.scheduleIdleLocked();
6173            }
6174        }
6175
6176        return didSomething;
6177    }
6178
6179    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6180        ProcessRecord old = mProcessNames.remove(name, uid);
6181        if (old != null) {
6182            old.uidRecord.numProcs--;
6183            if (old.uidRecord.numProcs == 0) {
6184                // No more processes using this uid, tell clients it is gone.
6185                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6186                        "No more processes in " + old.uidRecord);
6187                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6188                mActiveUids.remove(uid);
6189                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6190            }
6191            old.uidRecord = null;
6192        }
6193        mIsolatedProcesses.remove(uid);
6194        return old;
6195    }
6196
6197    private final void addProcessNameLocked(ProcessRecord proc) {
6198        // We shouldn't already have a process under this name, but just in case we
6199        // need to clean up whatever may be there now.
6200        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6201        if (old == proc && proc.persistent) {
6202            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6203            Slog.w(TAG, "Re-adding persistent process " + proc);
6204        } else if (old != null) {
6205            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6206        }
6207        UidRecord uidRec = mActiveUids.get(proc.uid);
6208        if (uidRec == null) {
6209            uidRec = new UidRecord(proc.uid);
6210            // This is the first appearance of the uid, report it now!
6211            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6212                    "Creating new process uid: " + uidRec);
6213            mActiveUids.put(proc.uid, uidRec);
6214            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6215            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6216        }
6217        proc.uidRecord = uidRec;
6218        uidRec.numProcs++;
6219        mProcessNames.put(proc.processName, proc.uid, proc);
6220        if (proc.isolated) {
6221            mIsolatedProcesses.put(proc.uid, proc);
6222        }
6223    }
6224
6225    boolean removeProcessLocked(ProcessRecord app,
6226            boolean callerWillRestart, boolean allowRestart, String reason) {
6227        final String name = app.processName;
6228        final int uid = app.uid;
6229        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6230            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6231
6232        ProcessRecord old = mProcessNames.get(name, uid);
6233        if (old != app) {
6234            // This process is no longer active, so nothing to do.
6235            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6236            return false;
6237        }
6238        removeProcessNameLocked(name, uid);
6239        if (mHeavyWeightProcess == app) {
6240            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6241                    mHeavyWeightProcess.userId, 0));
6242            mHeavyWeightProcess = null;
6243        }
6244        boolean needRestart = false;
6245        if (app.pid > 0 && app.pid != MY_PID) {
6246            int pid = app.pid;
6247            synchronized (mPidsSelfLocked) {
6248                mPidsSelfLocked.remove(pid);
6249                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6250            }
6251            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6252            if (app.isolated) {
6253                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6254            }
6255            boolean willRestart = false;
6256            if (app.persistent && !app.isolated) {
6257                if (!callerWillRestart) {
6258                    willRestart = true;
6259                } else {
6260                    needRestart = true;
6261                }
6262            }
6263            app.kill(reason, true);
6264            handleAppDiedLocked(app, willRestart, allowRestart);
6265            if (willRestart) {
6266                removeLruProcessLocked(app);
6267                addAppLocked(app.info, false, null /* ABI override */);
6268            }
6269        } else {
6270            mRemovedProcesses.add(app);
6271        }
6272
6273        return needRestart;
6274    }
6275
6276    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6277        cleanupAppInLaunchingProvidersLocked(app, true);
6278        removeProcessLocked(app, false, true, "timeout publishing content providers");
6279    }
6280
6281    private final void processStartTimedOutLocked(ProcessRecord app) {
6282        final int pid = app.pid;
6283        boolean gone = false;
6284        synchronized (mPidsSelfLocked) {
6285            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6286            if (knownApp != null && knownApp.thread == null) {
6287                mPidsSelfLocked.remove(pid);
6288                gone = true;
6289            }
6290        }
6291
6292        if (gone) {
6293            Slog.w(TAG, "Process " + app + " failed to attach");
6294            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6295                    pid, app.uid, app.processName);
6296            removeProcessNameLocked(app.processName, app.uid);
6297            if (mHeavyWeightProcess == app) {
6298                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6299                        mHeavyWeightProcess.userId, 0));
6300                mHeavyWeightProcess = null;
6301            }
6302            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6303            if (app.isolated) {
6304                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6305            }
6306            // Take care of any launching providers waiting for this process.
6307            cleanupAppInLaunchingProvidersLocked(app, true);
6308            // Take care of any services that are waiting for the process.
6309            mServices.processStartTimedOutLocked(app);
6310            app.kill("start timeout", true);
6311            removeLruProcessLocked(app);
6312            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6313                Slog.w(TAG, "Unattached app died before backup, skipping");
6314                try {
6315                    IBackupManager bm = IBackupManager.Stub.asInterface(
6316                            ServiceManager.getService(Context.BACKUP_SERVICE));
6317                    bm.agentDisconnected(app.info.packageName);
6318                } catch (RemoteException e) {
6319                    // Can't happen; the backup manager is local
6320                }
6321            }
6322            if (isPendingBroadcastProcessLocked(pid)) {
6323                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6324                skipPendingBroadcastLocked(pid);
6325            }
6326        } else {
6327            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6328        }
6329    }
6330
6331    private final boolean attachApplicationLocked(IApplicationThread thread,
6332            int pid) {
6333
6334        // Find the application record that is being attached...  either via
6335        // the pid if we are running in multiple processes, or just pull the
6336        // next app record if we are emulating process with anonymous threads.
6337        ProcessRecord app;
6338        if (pid != MY_PID && pid >= 0) {
6339            synchronized (mPidsSelfLocked) {
6340                app = mPidsSelfLocked.get(pid);
6341            }
6342        } else {
6343            app = null;
6344        }
6345
6346        if (app == null) {
6347            Slog.w(TAG, "No pending application record for pid " + pid
6348                    + " (IApplicationThread " + thread + "); dropping process");
6349            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6350            if (pid > 0 && pid != MY_PID) {
6351                Process.killProcessQuiet(pid);
6352                //TODO: killProcessGroup(app.info.uid, pid);
6353            } else {
6354                try {
6355                    thread.scheduleExit();
6356                } catch (Exception e) {
6357                    // Ignore exceptions.
6358                }
6359            }
6360            return false;
6361        }
6362
6363        // If this application record is still attached to a previous
6364        // process, clean it up now.
6365        if (app.thread != null) {
6366            handleAppDiedLocked(app, true, true);
6367        }
6368
6369        // Tell the process all about itself.
6370
6371        if (DEBUG_ALL) Slog.v(
6372                TAG, "Binding process pid " + pid + " to record " + app);
6373
6374        final String processName = app.processName;
6375        try {
6376            AppDeathRecipient adr = new AppDeathRecipient(
6377                    app, pid, thread);
6378            thread.asBinder().linkToDeath(adr, 0);
6379            app.deathRecipient = adr;
6380        } catch (RemoteException e) {
6381            app.resetPackageList(mProcessStats);
6382            startProcessLocked(app, "link fail", processName);
6383            return false;
6384        }
6385
6386        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6387
6388        app.makeActive(thread, mProcessStats);
6389        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6390        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6391        app.forcingToForeground = null;
6392        updateProcessForegroundLocked(app, false, false);
6393        app.hasShownUi = false;
6394        app.debugging = false;
6395        app.cached = false;
6396        app.killedByAm = false;
6397
6398        // We carefully use the same state that PackageManager uses for
6399        // filtering, since we use this flag to decide if we need to install
6400        // providers when user is unlocked later
6401        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6402
6403        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6404
6405        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6406        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6407
6408        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6409            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6410            msg.obj = app;
6411            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6412        }
6413
6414        if (!normalMode) {
6415            Slog.i(TAG, "Launching preboot mode app: " + app);
6416        }
6417
6418        if (DEBUG_ALL) Slog.v(
6419            TAG, "New app record " + app
6420            + " thread=" + thread.asBinder() + " pid=" + pid);
6421        try {
6422            int testMode = IApplicationThread.DEBUG_OFF;
6423            if (mDebugApp != null && mDebugApp.equals(processName)) {
6424                testMode = mWaitForDebugger
6425                    ? IApplicationThread.DEBUG_WAIT
6426                    : IApplicationThread.DEBUG_ON;
6427                app.debugging = true;
6428                if (mDebugTransient) {
6429                    mDebugApp = mOrigDebugApp;
6430                    mWaitForDebugger = mOrigWaitForDebugger;
6431                }
6432            }
6433            String profileFile = app.instrumentationProfileFile;
6434            ParcelFileDescriptor profileFd = null;
6435            int samplingInterval = 0;
6436            boolean profileAutoStop = false;
6437            if (mProfileApp != null && mProfileApp.equals(processName)) {
6438                mProfileProc = app;
6439                profileFile = mProfileFile;
6440                profileFd = mProfileFd;
6441                samplingInterval = mSamplingInterval;
6442                profileAutoStop = mAutoStopProfiler;
6443            }
6444            boolean enableTrackAllocation = false;
6445            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6446                enableTrackAllocation = true;
6447                mTrackAllocationApp = null;
6448            }
6449
6450            // If the app is being launched for restore or full backup, set it up specially
6451            boolean isRestrictedBackupMode = false;
6452            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6453                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6454                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6455                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6456                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6457            }
6458
6459            if (app.instrumentationClass != null) {
6460                notifyPackageUse(app.instrumentationClass.getPackageName(),
6461                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6462            }
6463            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6464                    + processName + " with config " + mConfiguration);
6465            ApplicationInfo appInfo = app.instrumentationInfo != null
6466                    ? app.instrumentationInfo : app.info;
6467            app.compat = compatibilityInfoForPackageLocked(appInfo);
6468            if (profileFd != null) {
6469                profileFd = profileFd.dup();
6470            }
6471            ProfilerInfo profilerInfo = profileFile == null ? null
6472                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6473            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6474                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6475                    app.instrumentationUiAutomationConnection, testMode,
6476                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6477                    isRestrictedBackupMode || !normalMode, app.persistent,
6478                    new Configuration(mConfiguration), app.compat,
6479                    getCommonServicesLocked(app.isolated),
6480                    mCoreSettingsObserver.getCoreSettingsLocked());
6481            updateLruProcessLocked(app, false, null);
6482            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6483        } catch (Exception e) {
6484            // todo: Yikes!  What should we do?  For now we will try to
6485            // start another process, but that could easily get us in
6486            // an infinite loop of restarting processes...
6487            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6488
6489            app.resetPackageList(mProcessStats);
6490            app.unlinkDeathRecipient();
6491            startProcessLocked(app, "bind fail", processName);
6492            return false;
6493        }
6494
6495        // Remove this record from the list of starting applications.
6496        mPersistentStartingProcesses.remove(app);
6497        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6498                "Attach application locked removing on hold: " + app);
6499        mProcessesOnHold.remove(app);
6500
6501        boolean badApp = false;
6502        boolean didSomething = false;
6503
6504        // See if the top visible activity is waiting to run in this process...
6505        if (normalMode) {
6506            try {
6507                if (mStackSupervisor.attachApplicationLocked(app)) {
6508                    didSomething = true;
6509                }
6510            } catch (Exception e) {
6511                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6512                badApp = true;
6513            }
6514        }
6515
6516        // Find any services that should be running in this process...
6517        if (!badApp) {
6518            try {
6519                didSomething |= mServices.attachApplicationLocked(app, processName);
6520            } catch (Exception e) {
6521                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6522                badApp = true;
6523            }
6524        }
6525
6526        // Check if a next-broadcast receiver is in this process...
6527        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6528            try {
6529                didSomething |= sendPendingBroadcastsLocked(app);
6530            } catch (Exception e) {
6531                // If the app died trying to launch the receiver we declare it 'bad'
6532                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6533                badApp = true;
6534            }
6535        }
6536
6537        // Check whether the next backup agent is in this process...
6538        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6539            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6540                    "New app is backup target, launching agent for " + app);
6541            notifyPackageUse(mBackupTarget.appInfo.packageName,
6542                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6543            try {
6544                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6545                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6546                        mBackupTarget.backupMode);
6547            } catch (Exception e) {
6548                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6549                badApp = true;
6550            }
6551        }
6552
6553        if (badApp) {
6554            app.kill("error during init", true);
6555            handleAppDiedLocked(app, false, true);
6556            return false;
6557        }
6558
6559        if (!didSomething) {
6560            updateOomAdjLocked();
6561        }
6562
6563        return true;
6564    }
6565
6566    @Override
6567    public final void attachApplication(IApplicationThread thread) {
6568        synchronized (this) {
6569            int callingPid = Binder.getCallingPid();
6570            final long origId = Binder.clearCallingIdentity();
6571            attachApplicationLocked(thread, callingPid);
6572            Binder.restoreCallingIdentity(origId);
6573        }
6574    }
6575
6576    @Override
6577    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6578        final long origId = Binder.clearCallingIdentity();
6579        synchronized (this) {
6580            ActivityStack stack = ActivityRecord.getStackLocked(token);
6581            if (stack != null) {
6582                ActivityRecord r =
6583                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6584                if (stopProfiling) {
6585                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6586                        try {
6587                            mProfileFd.close();
6588                        } catch (IOException e) {
6589                        }
6590                        clearProfilerLocked();
6591                    }
6592                }
6593            }
6594        }
6595        Binder.restoreCallingIdentity(origId);
6596    }
6597
6598    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6599        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6600                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6601    }
6602
6603    void enableScreenAfterBoot() {
6604        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6605                SystemClock.uptimeMillis());
6606        mWindowManager.enableScreenAfterBoot();
6607
6608        synchronized (this) {
6609            updateEventDispatchingLocked();
6610        }
6611    }
6612
6613    @Override
6614    public void showBootMessage(final CharSequence msg, final boolean always) {
6615        if (Binder.getCallingUid() != Process.myUid()) {
6616            // These days only the core system can call this, so apps can't get in
6617            // the way of what we show about running them.
6618        }
6619        mWindowManager.showBootMessage(msg, always);
6620    }
6621
6622    @Override
6623    public void keyguardWaitingForActivityDrawn() {
6624        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6625        final long token = Binder.clearCallingIdentity();
6626        try {
6627            synchronized (this) {
6628                if (DEBUG_LOCKSCREEN) logLockScreen("");
6629                mWindowManager.keyguardWaitingForActivityDrawn();
6630                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6631                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6632                    updateSleepIfNeededLocked();
6633                }
6634            }
6635        } finally {
6636            Binder.restoreCallingIdentity(token);
6637        }
6638    }
6639
6640    @Override
6641    public void keyguardGoingAway(int flags) {
6642        enforceNotIsolatedCaller("keyguardGoingAway");
6643        final long token = Binder.clearCallingIdentity();
6644        try {
6645            synchronized (this) {
6646                if (DEBUG_LOCKSCREEN) logLockScreen("");
6647                mWindowManager.keyguardGoingAway(flags);
6648                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6649                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6650                    updateSleepIfNeededLocked();
6651
6652                    // Some stack visibility might change (e.g. docked stack)
6653                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6654                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6655                }
6656            }
6657        } finally {
6658            Binder.restoreCallingIdentity(token);
6659        }
6660    }
6661
6662    final void finishBooting() {
6663        synchronized (this) {
6664            if (!mBootAnimationComplete) {
6665                mCallFinishBooting = true;
6666                return;
6667            }
6668            mCallFinishBooting = false;
6669        }
6670
6671        ArraySet<String> completedIsas = new ArraySet<String>();
6672        for (String abi : Build.SUPPORTED_ABIS) {
6673            Process.establishZygoteConnectionForAbi(abi);
6674            final String instructionSet = VMRuntime.getInstructionSet(abi);
6675            if (!completedIsas.contains(instructionSet)) {
6676                try {
6677                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6678                } catch (InstallerException e) {
6679                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6680                            e.getMessage() +")");
6681                }
6682                completedIsas.add(instructionSet);
6683            }
6684        }
6685
6686        IntentFilter pkgFilter = new IntentFilter();
6687        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6688        pkgFilter.addDataScheme("package");
6689        mContext.registerReceiver(new BroadcastReceiver() {
6690            @Override
6691            public void onReceive(Context context, Intent intent) {
6692                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6693                if (pkgs != null) {
6694                    for (String pkg : pkgs) {
6695                        synchronized (ActivityManagerService.this) {
6696                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6697                                    0, "query restart")) {
6698                                setResultCode(Activity.RESULT_OK);
6699                                return;
6700                            }
6701                        }
6702                    }
6703                }
6704            }
6705        }, pkgFilter);
6706
6707        IntentFilter dumpheapFilter = new IntentFilter();
6708        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6709        mContext.registerReceiver(new BroadcastReceiver() {
6710            @Override
6711            public void onReceive(Context context, Intent intent) {
6712                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6713                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6714                } else {
6715                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6716                }
6717            }
6718        }, dumpheapFilter);
6719
6720        // Let system services know.
6721        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6722
6723        synchronized (this) {
6724            // Ensure that any processes we had put on hold are now started
6725            // up.
6726            final int NP = mProcessesOnHold.size();
6727            if (NP > 0) {
6728                ArrayList<ProcessRecord> procs =
6729                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6730                for (int ip=0; ip<NP; ip++) {
6731                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6732                            + procs.get(ip));
6733                    startProcessLocked(procs.get(ip), "on-hold", null);
6734                }
6735            }
6736
6737            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6738                // Start looking for apps that are abusing wake locks.
6739                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6740                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6741                // Tell anyone interested that we are done booting!
6742                SystemProperties.set("sys.boot_completed", "1");
6743
6744                // And trigger dev.bootcomplete if we are not showing encryption progress
6745                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6746                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6747                    SystemProperties.set("dev.bootcomplete", "1");
6748                }
6749                mUserController.sendBootCompletedLocked(
6750                        new IIntentReceiver.Stub() {
6751                            @Override
6752                            public void performReceive(Intent intent, int resultCode,
6753                                    String data, Bundle extras, boolean ordered,
6754                                    boolean sticky, int sendingUser) {
6755                                synchronized (ActivityManagerService.this) {
6756                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6757                                            true, false);
6758                                }
6759                            }
6760                        });
6761                scheduleStartProfilesLocked();
6762            }
6763        }
6764    }
6765
6766    @Override
6767    public void bootAnimationComplete() {
6768        final boolean callFinishBooting;
6769        synchronized (this) {
6770            callFinishBooting = mCallFinishBooting;
6771            mBootAnimationComplete = true;
6772        }
6773        if (callFinishBooting) {
6774            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6775            finishBooting();
6776            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6777        }
6778    }
6779
6780    final void ensureBootCompleted() {
6781        boolean booting;
6782        boolean enableScreen;
6783        synchronized (this) {
6784            booting = mBooting;
6785            mBooting = false;
6786            enableScreen = !mBooted;
6787            mBooted = true;
6788        }
6789
6790        if (booting) {
6791            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6792            finishBooting();
6793            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6794        }
6795
6796        if (enableScreen) {
6797            enableScreenAfterBoot();
6798        }
6799    }
6800
6801    @Override
6802    public final void activityResumed(IBinder token) {
6803        final long origId = Binder.clearCallingIdentity();
6804        synchronized(this) {
6805            ActivityStack stack = ActivityRecord.getStackLocked(token);
6806            if (stack != null) {
6807                stack.activityResumedLocked(token);
6808            }
6809        }
6810        Binder.restoreCallingIdentity(origId);
6811    }
6812
6813    @Override
6814    public final void activityPaused(IBinder token) {
6815        final long origId = Binder.clearCallingIdentity();
6816        synchronized(this) {
6817            ActivityStack stack = ActivityRecord.getStackLocked(token);
6818            if (stack != null) {
6819                stack.activityPausedLocked(token, false);
6820            }
6821        }
6822        Binder.restoreCallingIdentity(origId);
6823    }
6824
6825    @Override
6826    public final void activityStopped(IBinder token, Bundle icicle,
6827            PersistableBundle persistentState, CharSequence description) {
6828        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6829
6830        // Refuse possible leaked file descriptors
6831        if (icicle != null && icicle.hasFileDescriptors()) {
6832            throw new IllegalArgumentException("File descriptors passed in Bundle");
6833        }
6834
6835        final long origId = Binder.clearCallingIdentity();
6836
6837        synchronized (this) {
6838            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6839            if (r != null) {
6840                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6841            }
6842        }
6843
6844        trimApplications();
6845
6846        Binder.restoreCallingIdentity(origId);
6847    }
6848
6849    @Override
6850    public final void activityDestroyed(IBinder token) {
6851        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6852        synchronized (this) {
6853            ActivityStack stack = ActivityRecord.getStackLocked(token);
6854            if (stack != null) {
6855                stack.activityDestroyedLocked(token, "activityDestroyed");
6856            }
6857        }
6858    }
6859
6860    @Override
6861    public final void activityRelaunched(IBinder token) {
6862        final long origId = Binder.clearCallingIdentity();
6863        synchronized (this) {
6864            mStackSupervisor.activityRelaunchedLocked(token);
6865        }
6866        Binder.restoreCallingIdentity(origId);
6867    }
6868
6869    @Override
6870    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6871            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6872        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6873                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6874        synchronized (this) {
6875            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6876            if (record == null) {
6877                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6878                        + "found for: " + token);
6879            }
6880            record.setSizeConfigurations(horizontalSizeConfiguration,
6881                    verticalSizeConfigurations, smallestSizeConfigurations);
6882        }
6883    }
6884
6885    @Override
6886    public final void backgroundResourcesReleased(IBinder token) {
6887        final long origId = Binder.clearCallingIdentity();
6888        try {
6889            synchronized (this) {
6890                ActivityStack stack = ActivityRecord.getStackLocked(token);
6891                if (stack != null) {
6892                    stack.backgroundResourcesReleased();
6893                }
6894            }
6895        } finally {
6896            Binder.restoreCallingIdentity(origId);
6897        }
6898    }
6899
6900    @Override
6901    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6902        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6903    }
6904
6905    @Override
6906    public final void notifyEnterAnimationComplete(IBinder token) {
6907        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6908    }
6909
6910    @Override
6911    public String getCallingPackage(IBinder token) {
6912        synchronized (this) {
6913            ActivityRecord r = getCallingRecordLocked(token);
6914            return r != null ? r.info.packageName : null;
6915        }
6916    }
6917
6918    @Override
6919    public ComponentName getCallingActivity(IBinder token) {
6920        synchronized (this) {
6921            ActivityRecord r = getCallingRecordLocked(token);
6922            return r != null ? r.intent.getComponent() : null;
6923        }
6924    }
6925
6926    private ActivityRecord getCallingRecordLocked(IBinder token) {
6927        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6928        if (r == null) {
6929            return null;
6930        }
6931        return r.resultTo;
6932    }
6933
6934    @Override
6935    public ComponentName getActivityClassForToken(IBinder token) {
6936        synchronized(this) {
6937            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6938            if (r == null) {
6939                return null;
6940            }
6941            return r.intent.getComponent();
6942        }
6943    }
6944
6945    @Override
6946    public String getPackageForToken(IBinder token) {
6947        synchronized(this) {
6948            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6949            if (r == null) {
6950                return null;
6951            }
6952            return r.packageName;
6953        }
6954    }
6955
6956    @Override
6957    public boolean isRootVoiceInteraction(IBinder token) {
6958        synchronized(this) {
6959            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6960            if (r == null) {
6961                return false;
6962            }
6963            return r.rootVoiceInteraction;
6964        }
6965    }
6966
6967    @Override
6968    public IIntentSender getIntentSender(int type,
6969            String packageName, IBinder token, String resultWho,
6970            int requestCode, Intent[] intents, String[] resolvedTypes,
6971            int flags, Bundle bOptions, int userId) {
6972        enforceNotIsolatedCaller("getIntentSender");
6973        // Refuse possible leaked file descriptors
6974        if (intents != null) {
6975            if (intents.length < 1) {
6976                throw new IllegalArgumentException("Intents array length must be >= 1");
6977            }
6978            for (int i=0; i<intents.length; i++) {
6979                Intent intent = intents[i];
6980                if (intent != null) {
6981                    if (intent.hasFileDescriptors()) {
6982                        throw new IllegalArgumentException("File descriptors passed in Intent");
6983                    }
6984                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6985                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6986                        throw new IllegalArgumentException(
6987                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6988                    }
6989                    intents[i] = new Intent(intent);
6990                }
6991            }
6992            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6993                throw new IllegalArgumentException(
6994                        "Intent array length does not match resolvedTypes length");
6995            }
6996        }
6997        if (bOptions != null) {
6998            if (bOptions.hasFileDescriptors()) {
6999                throw new IllegalArgumentException("File descriptors passed in options");
7000            }
7001        }
7002
7003        synchronized(this) {
7004            int callingUid = Binder.getCallingUid();
7005            int origUserId = userId;
7006            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7007                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7008                    ALLOW_NON_FULL, "getIntentSender", null);
7009            if (origUserId == UserHandle.USER_CURRENT) {
7010                // We don't want to evaluate this until the pending intent is
7011                // actually executed.  However, we do want to always do the
7012                // security checking for it above.
7013                userId = UserHandle.USER_CURRENT;
7014            }
7015            try {
7016                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7017                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7018                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7019                    if (!UserHandle.isSameApp(callingUid, uid)) {
7020                        String msg = "Permission Denial: getIntentSender() from pid="
7021                            + Binder.getCallingPid()
7022                            + ", uid=" + Binder.getCallingUid()
7023                            + ", (need uid=" + uid + ")"
7024                            + " is not allowed to send as package " + packageName;
7025                        Slog.w(TAG, msg);
7026                        throw new SecurityException(msg);
7027                    }
7028                }
7029
7030                return getIntentSenderLocked(type, packageName, callingUid, userId,
7031                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7032
7033            } catch (RemoteException e) {
7034                throw new SecurityException(e);
7035            }
7036        }
7037    }
7038
7039    IIntentSender getIntentSenderLocked(int type, String packageName,
7040            int callingUid, int userId, IBinder token, String resultWho,
7041            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7042            Bundle bOptions) {
7043        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7044        ActivityRecord activity = null;
7045        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7046            activity = ActivityRecord.isInStackLocked(token);
7047            if (activity == null) {
7048                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7049                return null;
7050            }
7051            if (activity.finishing) {
7052                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7053                return null;
7054            }
7055        }
7056
7057        // We're going to be splicing together extras before sending, so we're
7058        // okay poking into any contained extras.
7059        if (intents != null) {
7060            for (int i = 0; i < intents.length; i++) {
7061                intents[i].setDefusable(true);
7062            }
7063        }
7064        Bundle.setDefusable(bOptions, true);
7065
7066        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7067        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7068        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7069        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7070                |PendingIntent.FLAG_UPDATE_CURRENT);
7071
7072        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7073                type, packageName, activity, resultWho,
7074                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7075        WeakReference<PendingIntentRecord> ref;
7076        ref = mIntentSenderRecords.get(key);
7077        PendingIntentRecord rec = ref != null ? ref.get() : null;
7078        if (rec != null) {
7079            if (!cancelCurrent) {
7080                if (updateCurrent) {
7081                    if (rec.key.requestIntent != null) {
7082                        rec.key.requestIntent.replaceExtras(intents != null ?
7083                                intents[intents.length - 1] : null);
7084                    }
7085                    if (intents != null) {
7086                        intents[intents.length-1] = rec.key.requestIntent;
7087                        rec.key.allIntents = intents;
7088                        rec.key.allResolvedTypes = resolvedTypes;
7089                    } else {
7090                        rec.key.allIntents = null;
7091                        rec.key.allResolvedTypes = null;
7092                    }
7093                }
7094                return rec;
7095            }
7096            rec.canceled = true;
7097            mIntentSenderRecords.remove(key);
7098        }
7099        if (noCreate) {
7100            return rec;
7101        }
7102        rec = new PendingIntentRecord(this, key, callingUid);
7103        mIntentSenderRecords.put(key, rec.ref);
7104        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7105            if (activity.pendingResults == null) {
7106                activity.pendingResults
7107                        = new HashSet<WeakReference<PendingIntentRecord>>();
7108            }
7109            activity.pendingResults.add(rec.ref);
7110        }
7111        return rec;
7112    }
7113
7114    @Override
7115    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7116            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7117        if (target instanceof PendingIntentRecord) {
7118            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7119                    finishedReceiver, requiredPermission, options);
7120        } else {
7121            if (intent == null) {
7122                // Weird case: someone has given us their own custom IIntentSender, and now
7123                // they have someone else trying to send to it but of course this isn't
7124                // really a PendingIntent, so there is no base Intent, and the caller isn't
7125                // supplying an Intent... but we never want to dispatch a null Intent to
7126                // a receiver, so um...  let's make something up.
7127                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7128                intent = new Intent(Intent.ACTION_MAIN);
7129            }
7130            try {
7131                target.send(code, intent, resolvedType, null, requiredPermission, options);
7132            } catch (RemoteException e) {
7133            }
7134            // Platform code can rely on getting a result back when the send is done, but if
7135            // this intent sender is from outside of the system we can't rely on it doing that.
7136            // So instead we don't give it the result receiver, and instead just directly
7137            // report the finish immediately.
7138            if (finishedReceiver != null) {
7139                try {
7140                    finishedReceiver.performReceive(intent, 0,
7141                            null, null, false, false, UserHandle.getCallingUserId());
7142                } catch (RemoteException e) {
7143                }
7144            }
7145            return 0;
7146        }
7147    }
7148
7149    /**
7150     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7151     *
7152     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7153     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7154     */
7155    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7156        if (DEBUG_WHITELISTS) {
7157            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7158                    + targetUid + ", " + duration + ")");
7159        }
7160        synchronized (mPidsSelfLocked) {
7161            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7162            if (pr == null) {
7163                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7164                return;
7165            }
7166            if (!pr.whitelistManager) {
7167                if (DEBUG_WHITELISTS) {
7168                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7169                            + callerPid + " is not allowed");
7170                }
7171                return;
7172            }
7173        }
7174
7175        final long token = Binder.clearCallingIdentity();
7176        try {
7177            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7178                    true, "pe from uid:" + callerUid);
7179        } finally {
7180            Binder.restoreCallingIdentity(token);
7181        }
7182    }
7183
7184    @Override
7185    public void cancelIntentSender(IIntentSender sender) {
7186        if (!(sender instanceof PendingIntentRecord)) {
7187            return;
7188        }
7189        synchronized(this) {
7190            PendingIntentRecord rec = (PendingIntentRecord)sender;
7191            try {
7192                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7193                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7194                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7195                    String msg = "Permission Denial: cancelIntentSender() from pid="
7196                        + Binder.getCallingPid()
7197                        + ", uid=" + Binder.getCallingUid()
7198                        + " is not allowed to cancel packges "
7199                        + rec.key.packageName;
7200                    Slog.w(TAG, msg);
7201                    throw new SecurityException(msg);
7202                }
7203            } catch (RemoteException e) {
7204                throw new SecurityException(e);
7205            }
7206            cancelIntentSenderLocked(rec, true);
7207        }
7208    }
7209
7210    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7211        rec.canceled = true;
7212        mIntentSenderRecords.remove(rec.key);
7213        if (cleanActivity && rec.key.activity != null) {
7214            rec.key.activity.pendingResults.remove(rec.ref);
7215        }
7216    }
7217
7218    @Override
7219    public String getPackageForIntentSender(IIntentSender pendingResult) {
7220        if (!(pendingResult instanceof PendingIntentRecord)) {
7221            return null;
7222        }
7223        try {
7224            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7225            return res.key.packageName;
7226        } catch (ClassCastException e) {
7227        }
7228        return null;
7229    }
7230
7231    @Override
7232    public int getUidForIntentSender(IIntentSender sender) {
7233        if (sender instanceof PendingIntentRecord) {
7234            try {
7235                PendingIntentRecord res = (PendingIntentRecord)sender;
7236                return res.uid;
7237            } catch (ClassCastException e) {
7238            }
7239        }
7240        return -1;
7241    }
7242
7243    @Override
7244    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7245        if (!(pendingResult instanceof PendingIntentRecord)) {
7246            return false;
7247        }
7248        try {
7249            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7250            if (res.key.allIntents == null) {
7251                return false;
7252            }
7253            for (int i=0; i<res.key.allIntents.length; i++) {
7254                Intent intent = res.key.allIntents[i];
7255                if (intent.getPackage() != null && intent.getComponent() != null) {
7256                    return false;
7257                }
7258            }
7259            return true;
7260        } catch (ClassCastException e) {
7261        }
7262        return false;
7263    }
7264
7265    @Override
7266    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7267        if (!(pendingResult instanceof PendingIntentRecord)) {
7268            return false;
7269        }
7270        try {
7271            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7272            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7273                return true;
7274            }
7275            return false;
7276        } catch (ClassCastException e) {
7277        }
7278        return false;
7279    }
7280
7281    @Override
7282    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7283        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7284                "getIntentForIntentSender()");
7285        if (!(pendingResult instanceof PendingIntentRecord)) {
7286            return null;
7287        }
7288        try {
7289            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7290            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7291        } catch (ClassCastException e) {
7292        }
7293        return null;
7294    }
7295
7296    @Override
7297    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7298        if (!(pendingResult instanceof PendingIntentRecord)) {
7299            return null;
7300        }
7301        try {
7302            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7303            synchronized (this) {
7304                return getTagForIntentSenderLocked(res, prefix);
7305            }
7306        } catch (ClassCastException e) {
7307        }
7308        return null;
7309    }
7310
7311    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7312        final Intent intent = res.key.requestIntent;
7313        if (intent != null) {
7314            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7315                    || res.lastTagPrefix.equals(prefix))) {
7316                return res.lastTag;
7317            }
7318            res.lastTagPrefix = prefix;
7319            final StringBuilder sb = new StringBuilder(128);
7320            if (prefix != null) {
7321                sb.append(prefix);
7322            }
7323            if (intent.getAction() != null) {
7324                sb.append(intent.getAction());
7325            } else if (intent.getComponent() != null) {
7326                intent.getComponent().appendShortString(sb);
7327            } else {
7328                sb.append("?");
7329            }
7330            return res.lastTag = sb.toString();
7331        }
7332        return null;
7333    }
7334
7335    @Override
7336    public void setProcessLimit(int max) {
7337        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7338                "setProcessLimit()");
7339        synchronized (this) {
7340            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7341            mProcessLimitOverride = max;
7342        }
7343        trimApplications();
7344    }
7345
7346    @Override
7347    public int getProcessLimit() {
7348        synchronized (this) {
7349            return mProcessLimitOverride;
7350        }
7351    }
7352
7353    void foregroundTokenDied(ForegroundToken token) {
7354        synchronized (ActivityManagerService.this) {
7355            synchronized (mPidsSelfLocked) {
7356                ForegroundToken cur
7357                    = mForegroundProcesses.get(token.pid);
7358                if (cur != token) {
7359                    return;
7360                }
7361                mForegroundProcesses.remove(token.pid);
7362                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7363                if (pr == null) {
7364                    return;
7365                }
7366                pr.forcingToForeground = null;
7367                updateProcessForegroundLocked(pr, false, false);
7368            }
7369            updateOomAdjLocked();
7370        }
7371    }
7372
7373    @Override
7374    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7375        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7376                "setProcessForeground()");
7377        synchronized(this) {
7378            boolean changed = false;
7379
7380            synchronized (mPidsSelfLocked) {
7381                ProcessRecord pr = mPidsSelfLocked.get(pid);
7382                if (pr == null && isForeground) {
7383                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7384                    return;
7385                }
7386                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7387                if (oldToken != null) {
7388                    oldToken.token.unlinkToDeath(oldToken, 0);
7389                    mForegroundProcesses.remove(pid);
7390                    if (pr != null) {
7391                        pr.forcingToForeground = null;
7392                    }
7393                    changed = true;
7394                }
7395                if (isForeground && token != null) {
7396                    ForegroundToken newToken = new ForegroundToken() {
7397                        @Override
7398                        public void binderDied() {
7399                            foregroundTokenDied(this);
7400                        }
7401                    };
7402                    newToken.pid = pid;
7403                    newToken.token = token;
7404                    try {
7405                        token.linkToDeath(newToken, 0);
7406                        mForegroundProcesses.put(pid, newToken);
7407                        pr.forcingToForeground = token;
7408                        changed = true;
7409                    } catch (RemoteException e) {
7410                        // If the process died while doing this, we will later
7411                        // do the cleanup with the process death link.
7412                    }
7413                }
7414            }
7415
7416            if (changed) {
7417                updateOomAdjLocked();
7418            }
7419        }
7420    }
7421
7422    @Override
7423    public boolean isAppForeground(int uid) throws RemoteException {
7424        synchronized (this) {
7425            UidRecord uidRec = mActiveUids.get(uid);
7426            if (uidRec == null || uidRec.idle) {
7427                return false;
7428            }
7429            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7430        }
7431    }
7432
7433    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7434    // be guarded by permission checking.
7435    int getUidState(int uid) {
7436        synchronized (this) {
7437            UidRecord uidRec = mActiveUids.get(uid);
7438            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7439        }
7440    }
7441
7442    @Override
7443    public boolean isInMultiWindowMode(IBinder token) {
7444        final long origId = Binder.clearCallingIdentity();
7445        try {
7446            synchronized(this) {
7447                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7448                if (r == null) {
7449                    return false;
7450                }
7451                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7452                return !r.task.mFullscreen;
7453            }
7454        } finally {
7455            Binder.restoreCallingIdentity(origId);
7456        }
7457    }
7458
7459    @Override
7460    public boolean isInPictureInPictureMode(IBinder token) {
7461        final long origId = Binder.clearCallingIdentity();
7462        try {
7463            synchronized(this) {
7464                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7465                if (stack == null) {
7466                    return false;
7467                }
7468                return stack.mStackId == PINNED_STACK_ID;
7469            }
7470        } finally {
7471            Binder.restoreCallingIdentity(origId);
7472        }
7473    }
7474
7475    @Override
7476    public void enterPictureInPictureMode(IBinder token) {
7477        final long origId = Binder.clearCallingIdentity();
7478        try {
7479            synchronized(this) {
7480                if (!mSupportsPictureInPicture) {
7481                    throw new IllegalStateException("enterPictureInPictureMode: "
7482                            + "Device doesn't support picture-in-picture mode.");
7483                }
7484
7485                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7486
7487                if (r == null) {
7488                    throw new IllegalStateException("enterPictureInPictureMode: "
7489                            + "Can't find activity for token=" + token);
7490                }
7491
7492                if (!r.supportsPictureInPicture()) {
7493                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7494                            + "Picture-In-Picture not supported for r=" + r);
7495                }
7496
7497                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7498                // current bounds.
7499                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7500                final Rect bounds = (pinnedStack != null)
7501                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7502
7503                mStackSupervisor.moveActivityToPinnedStackLocked(
7504                        r, "enterPictureInPictureMode", bounds);
7505            }
7506        } finally {
7507            Binder.restoreCallingIdentity(origId);
7508        }
7509    }
7510
7511    // =========================================================
7512    // PROCESS INFO
7513    // =========================================================
7514
7515    static class ProcessInfoService extends IProcessInfoService.Stub {
7516        final ActivityManagerService mActivityManagerService;
7517        ProcessInfoService(ActivityManagerService activityManagerService) {
7518            mActivityManagerService = activityManagerService;
7519        }
7520
7521        @Override
7522        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7523            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7524                    /*in*/ pids, /*out*/ states, null);
7525        }
7526
7527        @Override
7528        public void getProcessStatesAndOomScoresFromPids(
7529                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7530            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7531                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7532        }
7533    }
7534
7535    /**
7536     * For each PID in the given input array, write the current process state
7537     * for that process into the states array, or -1 to indicate that no
7538     * process with the given PID exists. If scores array is provided, write
7539     * the oom score for the process into the scores array, with INVALID_ADJ
7540     * indicating the PID doesn't exist.
7541     */
7542    public void getProcessStatesAndOomScoresForPIDs(
7543            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7544        if (scores != null) {
7545            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7546                    "getProcessStatesAndOomScoresForPIDs()");
7547        }
7548
7549        if (pids == null) {
7550            throw new NullPointerException("pids");
7551        } else if (states == null) {
7552            throw new NullPointerException("states");
7553        } else if (pids.length != states.length) {
7554            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7555        } else if (scores != null && pids.length != scores.length) {
7556            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7557        }
7558
7559        synchronized (mPidsSelfLocked) {
7560            for (int i = 0; i < pids.length; i++) {
7561                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7562                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7563                        pr.curProcState;
7564                if (scores != null) {
7565                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7566                }
7567            }
7568        }
7569    }
7570
7571    // =========================================================
7572    // PERMISSIONS
7573    // =========================================================
7574
7575    static class PermissionController extends IPermissionController.Stub {
7576        ActivityManagerService mActivityManagerService;
7577        PermissionController(ActivityManagerService activityManagerService) {
7578            mActivityManagerService = activityManagerService;
7579        }
7580
7581        @Override
7582        public boolean checkPermission(String permission, int pid, int uid) {
7583            return mActivityManagerService.checkPermission(permission, pid,
7584                    uid) == PackageManager.PERMISSION_GRANTED;
7585        }
7586
7587        @Override
7588        public String[] getPackagesForUid(int uid) {
7589            return mActivityManagerService.mContext.getPackageManager()
7590                    .getPackagesForUid(uid);
7591        }
7592
7593        @Override
7594        public boolean isRuntimePermission(String permission) {
7595            try {
7596                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7597                        .getPermissionInfo(permission, 0);
7598                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7599            } catch (NameNotFoundException nnfe) {
7600                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7601            }
7602            return false;
7603        }
7604    }
7605
7606    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7607        @Override
7608        public int checkComponentPermission(String permission, int pid, int uid,
7609                int owningUid, boolean exported) {
7610            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7611                    owningUid, exported);
7612        }
7613
7614        @Override
7615        public Object getAMSLock() {
7616            return ActivityManagerService.this;
7617        }
7618    }
7619
7620    /**
7621     * This can be called with or without the global lock held.
7622     */
7623    int checkComponentPermission(String permission, int pid, int uid,
7624            int owningUid, boolean exported) {
7625        if (pid == MY_PID) {
7626            return PackageManager.PERMISSION_GRANTED;
7627        }
7628        return ActivityManager.checkComponentPermission(permission, uid,
7629                owningUid, exported);
7630    }
7631
7632    /**
7633     * As the only public entry point for permissions checking, this method
7634     * can enforce the semantic that requesting a check on a null global
7635     * permission is automatically denied.  (Internally a null permission
7636     * string is used when calling {@link #checkComponentPermission} in cases
7637     * when only uid-based security is needed.)
7638     *
7639     * This can be called with or without the global lock held.
7640     */
7641    @Override
7642    public int checkPermission(String permission, int pid, int uid) {
7643        if (permission == null) {
7644            return PackageManager.PERMISSION_DENIED;
7645        }
7646        return checkComponentPermission(permission, pid, uid, -1, true);
7647    }
7648
7649    @Override
7650    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7651        if (permission == null) {
7652            return PackageManager.PERMISSION_DENIED;
7653        }
7654
7655        // We might be performing an operation on behalf of an indirect binder
7656        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7657        // client identity accordingly before proceeding.
7658        Identity tlsIdentity = sCallerIdentity.get();
7659        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7660            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7661                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7662            uid = tlsIdentity.uid;
7663            pid = tlsIdentity.pid;
7664        }
7665
7666        return checkComponentPermission(permission, pid, uid, -1, true);
7667    }
7668
7669    /**
7670     * Binder IPC calls go through the public entry point.
7671     * This can be called with or without the global lock held.
7672     */
7673    int checkCallingPermission(String permission) {
7674        return checkPermission(permission,
7675                Binder.getCallingPid(),
7676                UserHandle.getAppId(Binder.getCallingUid()));
7677    }
7678
7679    /**
7680     * This can be called with or without the global lock held.
7681     */
7682    void enforceCallingPermission(String permission, String func) {
7683        if (checkCallingPermission(permission)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return;
7686        }
7687
7688        String msg = "Permission Denial: " + func + " from pid="
7689                + Binder.getCallingPid()
7690                + ", uid=" + Binder.getCallingUid()
7691                + " requires " + permission;
7692        Slog.w(TAG, msg);
7693        throw new SecurityException(msg);
7694    }
7695
7696    /**
7697     * Determine if UID is holding permissions required to access {@link Uri} in
7698     * the given {@link ProviderInfo}. Final permission checking is always done
7699     * in {@link ContentProvider}.
7700     */
7701    private final boolean checkHoldingPermissionsLocked(
7702            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7703        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7704                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7705        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7706            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7707                    != PERMISSION_GRANTED) {
7708                return false;
7709            }
7710        }
7711        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7712    }
7713
7714    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7715            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7716        if (pi.applicationInfo.uid == uid) {
7717            return true;
7718        } else if (!pi.exported) {
7719            return false;
7720        }
7721
7722        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7723        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7724        try {
7725            // check if target holds top-level <provider> permissions
7726            if (!readMet && pi.readPermission != null && considerUidPermissions
7727                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7728                readMet = true;
7729            }
7730            if (!writeMet && pi.writePermission != null && considerUidPermissions
7731                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7732                writeMet = true;
7733            }
7734
7735            // track if unprotected read/write is allowed; any denied
7736            // <path-permission> below removes this ability
7737            boolean allowDefaultRead = pi.readPermission == null;
7738            boolean allowDefaultWrite = pi.writePermission == null;
7739
7740            // check if target holds any <path-permission> that match uri
7741            final PathPermission[] pps = pi.pathPermissions;
7742            if (pps != null) {
7743                final String path = grantUri.uri.getPath();
7744                int i = pps.length;
7745                while (i > 0 && (!readMet || !writeMet)) {
7746                    i--;
7747                    PathPermission pp = pps[i];
7748                    if (pp.match(path)) {
7749                        if (!readMet) {
7750                            final String pprperm = pp.getReadPermission();
7751                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7752                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7753                                    + ": match=" + pp.match(path)
7754                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7755                            if (pprperm != null) {
7756                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7757                                        == PERMISSION_GRANTED) {
7758                                    readMet = true;
7759                                } else {
7760                                    allowDefaultRead = false;
7761                                }
7762                            }
7763                        }
7764                        if (!writeMet) {
7765                            final String ppwperm = pp.getWritePermission();
7766                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7767                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7768                                    + ": match=" + pp.match(path)
7769                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7770                            if (ppwperm != null) {
7771                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7772                                        == PERMISSION_GRANTED) {
7773                                    writeMet = true;
7774                                } else {
7775                                    allowDefaultWrite = false;
7776                                }
7777                            }
7778                        }
7779                    }
7780                }
7781            }
7782
7783            // grant unprotected <provider> read/write, if not blocked by
7784            // <path-permission> above
7785            if (allowDefaultRead) readMet = true;
7786            if (allowDefaultWrite) writeMet = true;
7787
7788        } catch (RemoteException e) {
7789            return false;
7790        }
7791
7792        return readMet && writeMet;
7793    }
7794
7795    public int getAppStartMode(int uid, String packageName) {
7796        synchronized (this) {
7797            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7798        }
7799    }
7800
7801    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7802            boolean allowWhenForeground) {
7803        UidRecord uidRec = mActiveUids.get(uid);
7804        if (!mLenientBackgroundCheck) {
7805            if (!allowWhenForeground || uidRec == null
7806                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7807                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7808                        packageName) != AppOpsManager.MODE_ALLOWED) {
7809                    return ActivityManager.APP_START_MODE_DELAYED;
7810                }
7811            }
7812
7813        } else if (uidRec == null || uidRec.idle) {
7814            if (callingPid >= 0) {
7815                ProcessRecord proc;
7816                synchronized (mPidsSelfLocked) {
7817                    proc = mPidsSelfLocked.get(callingPid);
7818                }
7819                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7820                    // Whoever is instigating this is in the foreground, so we will allow it
7821                    // to go through.
7822                    return ActivityManager.APP_START_MODE_NORMAL;
7823                }
7824            }
7825            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7826                    != AppOpsManager.MODE_ALLOWED) {
7827                return ActivityManager.APP_START_MODE_DELAYED;
7828            }
7829        }
7830        return ActivityManager.APP_START_MODE_NORMAL;
7831    }
7832
7833    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7834        ProviderInfo pi = null;
7835        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7836        if (cpr != null) {
7837            pi = cpr.info;
7838        } else {
7839            try {
7840                pi = AppGlobals.getPackageManager().resolveContentProvider(
7841                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7842                        userHandle);
7843            } catch (RemoteException ex) {
7844            }
7845        }
7846        return pi;
7847    }
7848
7849    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7850        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7851        if (targetUris != null) {
7852            return targetUris.get(grantUri);
7853        }
7854        return null;
7855    }
7856
7857    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7858            String targetPkg, int targetUid, GrantUri grantUri) {
7859        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7860        if (targetUris == null) {
7861            targetUris = Maps.newArrayMap();
7862            mGrantedUriPermissions.put(targetUid, targetUris);
7863        }
7864
7865        UriPermission perm = targetUris.get(grantUri);
7866        if (perm == null) {
7867            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7868            targetUris.put(grantUri, perm);
7869        }
7870
7871        return perm;
7872    }
7873
7874    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7875            final int modeFlags) {
7876        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7877        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7878                : UriPermission.STRENGTH_OWNED;
7879
7880        // Root gets to do everything.
7881        if (uid == 0) {
7882            return true;
7883        }
7884
7885        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7886        if (perms == null) return false;
7887
7888        // First look for exact match
7889        final UriPermission exactPerm = perms.get(grantUri);
7890        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7891            return true;
7892        }
7893
7894        // No exact match, look for prefixes
7895        final int N = perms.size();
7896        for (int i = 0; i < N; i++) {
7897            final UriPermission perm = perms.valueAt(i);
7898            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7899                    && perm.getStrength(modeFlags) >= minStrength) {
7900                return true;
7901            }
7902        }
7903
7904        return false;
7905    }
7906
7907    /**
7908     * @param uri This uri must NOT contain an embedded userId.
7909     * @param userId The userId in which the uri is to be resolved.
7910     */
7911    @Override
7912    public int checkUriPermission(Uri uri, int pid, int uid,
7913            final int modeFlags, int userId, IBinder callerToken) {
7914        enforceNotIsolatedCaller("checkUriPermission");
7915
7916        // Another redirected-binder-call permissions check as in
7917        // {@link checkPermissionWithToken}.
7918        Identity tlsIdentity = sCallerIdentity.get();
7919        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7920            uid = tlsIdentity.uid;
7921            pid = tlsIdentity.pid;
7922        }
7923
7924        // Our own process gets to do everything.
7925        if (pid == MY_PID) {
7926            return PackageManager.PERMISSION_GRANTED;
7927        }
7928        synchronized (this) {
7929            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7930                    ? PackageManager.PERMISSION_GRANTED
7931                    : PackageManager.PERMISSION_DENIED;
7932        }
7933    }
7934
7935    /**
7936     * Check if the targetPkg can be granted permission to access uri by
7937     * the callingUid using the given modeFlags.  Throws a security exception
7938     * if callingUid is not allowed to do this.  Returns the uid of the target
7939     * if the URI permission grant should be performed; returns -1 if it is not
7940     * needed (for example targetPkg already has permission to access the URI).
7941     * If you already know the uid of the target, you can supply it in
7942     * lastTargetUid else set that to -1.
7943     */
7944    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7945            final int modeFlags, int lastTargetUid) {
7946        if (!Intent.isAccessUriMode(modeFlags)) {
7947            return -1;
7948        }
7949
7950        if (targetPkg != null) {
7951            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7952                    "Checking grant " + targetPkg + " permission to " + grantUri);
7953        }
7954
7955        final IPackageManager pm = AppGlobals.getPackageManager();
7956
7957        // If this is not a content: uri, we can't do anything with it.
7958        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7959            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7960                    "Can't grant URI permission for non-content URI: " + grantUri);
7961            return -1;
7962        }
7963
7964        final String authority = grantUri.uri.getAuthority();
7965        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7966                MATCH_DEBUG_TRIAGED_MISSING);
7967        if (pi == null) {
7968            Slog.w(TAG, "No content provider found for permission check: " +
7969                    grantUri.uri.toSafeString());
7970            return -1;
7971        }
7972
7973        int targetUid = lastTargetUid;
7974        if (targetUid < 0 && targetPkg != null) {
7975            try {
7976                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7977                        UserHandle.getUserId(callingUid));
7978                if (targetUid < 0) {
7979                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7980                            "Can't grant URI permission no uid for: " + targetPkg);
7981                    return -1;
7982                }
7983            } catch (RemoteException ex) {
7984                return -1;
7985            }
7986        }
7987
7988        if (targetUid >= 0) {
7989            // First...  does the target actually need this permission?
7990            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7991                // No need to grant the target this permission.
7992                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                        "Target " + targetPkg + " already has full permission to " + grantUri);
7994                return -1;
7995            }
7996        } else {
7997            // First...  there is no target package, so can anyone access it?
7998            boolean allowed = pi.exported;
7999            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8000                if (pi.readPermission != null) {
8001                    allowed = false;
8002                }
8003            }
8004            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8005                if (pi.writePermission != null) {
8006                    allowed = false;
8007                }
8008            }
8009            if (allowed) {
8010                return -1;
8011            }
8012        }
8013
8014        /* There is a special cross user grant if:
8015         * - The target is on another user.
8016         * - Apps on the current user can access the uri without any uid permissions.
8017         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8018         * grant uri permissions.
8019         */
8020        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8021                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8022                modeFlags, false /*without considering the uid permissions*/);
8023
8024        // Second...  is the provider allowing granting of URI permissions?
8025        if (!specialCrossUserGrant) {
8026            if (!pi.grantUriPermissions) {
8027                throw new SecurityException("Provider " + pi.packageName
8028                        + "/" + pi.name
8029                        + " does not allow granting of Uri permissions (uri "
8030                        + grantUri + ")");
8031            }
8032            if (pi.uriPermissionPatterns != null) {
8033                final int N = pi.uriPermissionPatterns.length;
8034                boolean allowed = false;
8035                for (int i=0; i<N; i++) {
8036                    if (pi.uriPermissionPatterns[i] != null
8037                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8038                        allowed = true;
8039                        break;
8040                    }
8041                }
8042                if (!allowed) {
8043                    throw new SecurityException("Provider " + pi.packageName
8044                            + "/" + pi.name
8045                            + " does not allow granting of permission to path of Uri "
8046                            + grantUri);
8047                }
8048            }
8049        }
8050
8051        // Third...  does the caller itself have permission to access
8052        // this uri?
8053        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8054            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8055                // Require they hold a strong enough Uri permission
8056                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8057                    throw new SecurityException("Uid " + callingUid
8058                            + " does not have permission to uri " + grantUri);
8059                }
8060            }
8061        }
8062        return targetUid;
8063    }
8064
8065    /**
8066     * @param uri This uri must NOT contain an embedded userId.
8067     * @param userId The userId in which the uri is to be resolved.
8068     */
8069    @Override
8070    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8071            final int modeFlags, int userId) {
8072        enforceNotIsolatedCaller("checkGrantUriPermission");
8073        synchronized(this) {
8074            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8075                    new GrantUri(userId, uri, false), modeFlags, -1);
8076        }
8077    }
8078
8079    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8080            final int modeFlags, UriPermissionOwner owner) {
8081        if (!Intent.isAccessUriMode(modeFlags)) {
8082            return;
8083        }
8084
8085        // So here we are: the caller has the assumed permission
8086        // to the uri, and the target doesn't.  Let's now give this to
8087        // the target.
8088
8089        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8090                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8091
8092        final String authority = grantUri.uri.getAuthority();
8093        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8094                MATCH_DEBUG_TRIAGED_MISSING);
8095        if (pi == null) {
8096            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8097            return;
8098        }
8099
8100        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8101            grantUri.prefix = true;
8102        }
8103        final UriPermission perm = findOrCreateUriPermissionLocked(
8104                pi.packageName, targetPkg, targetUid, grantUri);
8105        perm.grantModes(modeFlags, owner);
8106    }
8107
8108    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8109            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8110        if (targetPkg == null) {
8111            throw new NullPointerException("targetPkg");
8112        }
8113        int targetUid;
8114        final IPackageManager pm = AppGlobals.getPackageManager();
8115        try {
8116            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8117        } catch (RemoteException ex) {
8118            return;
8119        }
8120
8121        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8122                targetUid);
8123        if (targetUid < 0) {
8124            return;
8125        }
8126
8127        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8128                owner);
8129    }
8130
8131    static class NeededUriGrants extends ArrayList<GrantUri> {
8132        final String targetPkg;
8133        final int targetUid;
8134        final int flags;
8135
8136        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8137            this.targetPkg = targetPkg;
8138            this.targetUid = targetUid;
8139            this.flags = flags;
8140        }
8141    }
8142
8143    /**
8144     * Like checkGrantUriPermissionLocked, but takes an Intent.
8145     */
8146    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8147            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8148        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8149                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8150                + " clip=" + (intent != null ? intent.getClipData() : null)
8151                + " from " + intent + "; flags=0x"
8152                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8153
8154        if (targetPkg == null) {
8155            throw new NullPointerException("targetPkg");
8156        }
8157
8158        if (intent == null) {
8159            return null;
8160        }
8161        Uri data = intent.getData();
8162        ClipData clip = intent.getClipData();
8163        if (data == null && clip == null) {
8164            return null;
8165        }
8166        // Default userId for uris in the intent (if they don't specify it themselves)
8167        int contentUserHint = intent.getContentUserHint();
8168        if (contentUserHint == UserHandle.USER_CURRENT) {
8169            contentUserHint = UserHandle.getUserId(callingUid);
8170        }
8171        final IPackageManager pm = AppGlobals.getPackageManager();
8172        int targetUid;
8173        if (needed != null) {
8174            targetUid = needed.targetUid;
8175        } else {
8176            try {
8177                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8178                        targetUserId);
8179            } catch (RemoteException ex) {
8180                return null;
8181            }
8182            if (targetUid < 0) {
8183                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8184                        "Can't grant URI permission no uid for: " + targetPkg
8185                        + " on user " + targetUserId);
8186                return null;
8187            }
8188        }
8189        if (data != null) {
8190            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8191            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8192                    targetUid);
8193            if (targetUid > 0) {
8194                if (needed == null) {
8195                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8196                }
8197                needed.add(grantUri);
8198            }
8199        }
8200        if (clip != null) {
8201            for (int i=0; i<clip.getItemCount(); i++) {
8202                Uri uri = clip.getItemAt(i).getUri();
8203                if (uri != null) {
8204                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8205                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8206                            targetUid);
8207                    if (targetUid > 0) {
8208                        if (needed == null) {
8209                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8210                        }
8211                        needed.add(grantUri);
8212                    }
8213                } else {
8214                    Intent clipIntent = clip.getItemAt(i).getIntent();
8215                    if (clipIntent != null) {
8216                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8217                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8218                        if (newNeeded != null) {
8219                            needed = newNeeded;
8220                        }
8221                    }
8222                }
8223            }
8224        }
8225
8226        return needed;
8227    }
8228
8229    /**
8230     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8231     */
8232    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8233            UriPermissionOwner owner) {
8234        if (needed != null) {
8235            for (int i=0; i<needed.size(); i++) {
8236                GrantUri grantUri = needed.get(i);
8237                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8238                        grantUri, needed.flags, owner);
8239            }
8240        }
8241    }
8242
8243    void grantUriPermissionFromIntentLocked(int callingUid,
8244            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8245        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8246                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8247        if (needed == null) {
8248            return;
8249        }
8250
8251        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8252    }
8253
8254    /**
8255     * @param uri This uri must NOT contain an embedded userId.
8256     * @param userId The userId in which the uri is to be resolved.
8257     */
8258    @Override
8259    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8260            final int modeFlags, int userId) {
8261        enforceNotIsolatedCaller("grantUriPermission");
8262        GrantUri grantUri = new GrantUri(userId, uri, false);
8263        synchronized(this) {
8264            final ProcessRecord r = getRecordForAppLocked(caller);
8265            if (r == null) {
8266                throw new SecurityException("Unable to find app for caller "
8267                        + caller
8268                        + " when granting permission to uri " + grantUri);
8269            }
8270            if (targetPkg == null) {
8271                throw new IllegalArgumentException("null target");
8272            }
8273            if (grantUri == null) {
8274                throw new IllegalArgumentException("null uri");
8275            }
8276
8277            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8278                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8279                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8280                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8281
8282            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8283                    UserHandle.getUserId(r.uid));
8284        }
8285    }
8286
8287    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8288        if (perm.modeFlags == 0) {
8289            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8290                    perm.targetUid);
8291            if (perms != null) {
8292                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8294
8295                perms.remove(perm.uri);
8296                if (perms.isEmpty()) {
8297                    mGrantedUriPermissions.remove(perm.targetUid);
8298                }
8299            }
8300        }
8301    }
8302
8303    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8304        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8305                "Revoking all granted permissions to " + grantUri);
8306
8307        final IPackageManager pm = AppGlobals.getPackageManager();
8308        final String authority = grantUri.uri.getAuthority();
8309        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8310                MATCH_DEBUG_TRIAGED_MISSING);
8311        if (pi == null) {
8312            Slog.w(TAG, "No content provider found for permission revoke: "
8313                    + grantUri.toSafeString());
8314            return;
8315        }
8316
8317        // Does the caller have this permission on the URI?
8318        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8319            // If they don't have direct access to the URI, then revoke any
8320            // ownerless URI permissions that have been granted to them.
8321            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8322            if (perms != null) {
8323                boolean persistChanged = false;
8324                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8325                    final UriPermission perm = it.next();
8326                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8327                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8328                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8329                                "Revoking non-owned " + perm.targetUid
8330                                + " permission to " + perm.uri);
8331                        persistChanged |= perm.revokeModes(
8332                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8333                        if (perm.modeFlags == 0) {
8334                            it.remove();
8335                        }
8336                    }
8337                }
8338                if (perms.isEmpty()) {
8339                    mGrantedUriPermissions.remove(callingUid);
8340                }
8341                if (persistChanged) {
8342                    schedulePersistUriGrants();
8343                }
8344            }
8345            return;
8346        }
8347
8348        boolean persistChanged = false;
8349
8350        // Go through all of the permissions and remove any that match.
8351        int N = mGrantedUriPermissions.size();
8352        for (int i = 0; i < N; i++) {
8353            final int targetUid = mGrantedUriPermissions.keyAt(i);
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8355
8356            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8357                final UriPermission perm = it.next();
8358                if (perm.uri.sourceUserId == grantUri.sourceUserId
8359                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8360                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8361                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8362                    persistChanged |= perm.revokeModes(
8363                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8364                    if (perm.modeFlags == 0) {
8365                        it.remove();
8366                    }
8367                }
8368            }
8369
8370            if (perms.isEmpty()) {
8371                mGrantedUriPermissions.remove(targetUid);
8372                N--;
8373                i--;
8374            }
8375        }
8376
8377        if (persistChanged) {
8378            schedulePersistUriGrants();
8379        }
8380    }
8381
8382    /**
8383     * @param uri This uri must NOT contain an embedded userId.
8384     * @param userId The userId in which the uri is to be resolved.
8385     */
8386    @Override
8387    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8388            int userId) {
8389        enforceNotIsolatedCaller("revokeUriPermission");
8390        synchronized(this) {
8391            final ProcessRecord r = getRecordForAppLocked(caller);
8392            if (r == null) {
8393                throw new SecurityException("Unable to find app for caller "
8394                        + caller
8395                        + " when revoking permission to uri " + uri);
8396            }
8397            if (uri == null) {
8398                Slog.w(TAG, "revokeUriPermission: null uri");
8399                return;
8400            }
8401
8402            if (!Intent.isAccessUriMode(modeFlags)) {
8403                return;
8404            }
8405
8406            final String authority = uri.getAuthority();
8407            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8408                    MATCH_DEBUG_TRIAGED_MISSING);
8409            if (pi == null) {
8410                Slog.w(TAG, "No content provider found for permission revoke: "
8411                        + uri.toSafeString());
8412                return;
8413            }
8414
8415            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8416        }
8417    }
8418
8419    /**
8420     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8421     * given package.
8422     *
8423     * @param packageName Package name to match, or {@code null} to apply to all
8424     *            packages.
8425     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8426     *            to all users.
8427     * @param persistable If persistable grants should be removed.
8428     */
8429    private void removeUriPermissionsForPackageLocked(
8430            String packageName, int userHandle, boolean persistable) {
8431        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8432            throw new IllegalArgumentException("Must narrow by either package or user");
8433        }
8434
8435        boolean persistChanged = false;
8436
8437        int N = mGrantedUriPermissions.size();
8438        for (int i = 0; i < N; i++) {
8439            final int targetUid = mGrantedUriPermissions.keyAt(i);
8440            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8441
8442            // Only inspect grants matching user
8443            if (userHandle == UserHandle.USER_ALL
8444                    || userHandle == UserHandle.getUserId(targetUid)) {
8445                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8446                    final UriPermission perm = it.next();
8447
8448                    // Only inspect grants matching package
8449                    if (packageName == null || perm.sourcePkg.equals(packageName)
8450                            || perm.targetPkg.equals(packageName)) {
8451                        persistChanged |= perm.revokeModes(persistable
8452                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8453
8454                        // Only remove when no modes remain; any persisted grants
8455                        // will keep this alive.
8456                        if (perm.modeFlags == 0) {
8457                            it.remove();
8458                        }
8459                    }
8460                }
8461
8462                if (perms.isEmpty()) {
8463                    mGrantedUriPermissions.remove(targetUid);
8464                    N--;
8465                    i--;
8466                }
8467            }
8468        }
8469
8470        if (persistChanged) {
8471            schedulePersistUriGrants();
8472        }
8473    }
8474
8475    @Override
8476    public IBinder newUriPermissionOwner(String name) {
8477        enforceNotIsolatedCaller("newUriPermissionOwner");
8478        synchronized(this) {
8479            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8480            return owner.getExternalTokenLocked();
8481        }
8482    }
8483
8484    @Override
8485    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8486        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8487        synchronized(this) {
8488            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8489            if (r == null) {
8490                throw new IllegalArgumentException("Activity does not exist; token="
8491                        + activityToken);
8492            }
8493            return r.getUriPermissionsLocked().getExternalTokenLocked();
8494        }
8495    }
8496    /**
8497     * @param uri This uri must NOT contain an embedded userId.
8498     * @param sourceUserId The userId in which the uri is to be resolved.
8499     * @param targetUserId The userId of the app that receives the grant.
8500     */
8501    @Override
8502    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8503            final int modeFlags, int sourceUserId, int targetUserId) {
8504        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8505                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8506                "grantUriPermissionFromOwner", null);
8507        synchronized(this) {
8508            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8509            if (owner == null) {
8510                throw new IllegalArgumentException("Unknown owner: " + token);
8511            }
8512            if (fromUid != Binder.getCallingUid()) {
8513                if (Binder.getCallingUid() != Process.myUid()) {
8514                    // Only system code can grant URI permissions on behalf
8515                    // of other users.
8516                    throw new SecurityException("nice try");
8517                }
8518            }
8519            if (targetPkg == null) {
8520                throw new IllegalArgumentException("null target");
8521            }
8522            if (uri == null) {
8523                throw new IllegalArgumentException("null uri");
8524            }
8525
8526            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8527                    modeFlags, owner, targetUserId);
8528        }
8529    }
8530
8531    /**
8532     * @param uri This uri must NOT contain an embedded userId.
8533     * @param userId The userId in which the uri is to be resolved.
8534     */
8535    @Override
8536    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8537        synchronized(this) {
8538            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8539            if (owner == null) {
8540                throw new IllegalArgumentException("Unknown owner: " + token);
8541            }
8542
8543            if (uri == null) {
8544                owner.removeUriPermissionsLocked(mode);
8545            } else {
8546                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8547            }
8548        }
8549    }
8550
8551    private void schedulePersistUriGrants() {
8552        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8553            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8554                    10 * DateUtils.SECOND_IN_MILLIS);
8555        }
8556    }
8557
8558    private void writeGrantedUriPermissions() {
8559        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8560
8561        // Snapshot permissions so we can persist without lock
8562        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8563        synchronized (this) {
8564            final int size = mGrantedUriPermissions.size();
8565            for (int i = 0; i < size; i++) {
8566                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8567                for (UriPermission perm : perms.values()) {
8568                    if (perm.persistedModeFlags != 0) {
8569                        persist.add(perm.snapshot());
8570                    }
8571                }
8572            }
8573        }
8574
8575        FileOutputStream fos = null;
8576        try {
8577            fos = mGrantFile.startWrite();
8578
8579            XmlSerializer out = new FastXmlSerializer();
8580            out.setOutput(fos, StandardCharsets.UTF_8.name());
8581            out.startDocument(null, true);
8582            out.startTag(null, TAG_URI_GRANTS);
8583            for (UriPermission.Snapshot perm : persist) {
8584                out.startTag(null, TAG_URI_GRANT);
8585                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8586                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8587                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8588                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8589                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8590                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8591                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8592                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8593                out.endTag(null, TAG_URI_GRANT);
8594            }
8595            out.endTag(null, TAG_URI_GRANTS);
8596            out.endDocument();
8597
8598            mGrantFile.finishWrite(fos);
8599        } catch (IOException e) {
8600            if (fos != null) {
8601                mGrantFile.failWrite(fos);
8602            }
8603        }
8604    }
8605
8606    private void readGrantedUriPermissionsLocked() {
8607        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8608
8609        final long now = System.currentTimeMillis();
8610
8611        FileInputStream fis = null;
8612        try {
8613            fis = mGrantFile.openRead();
8614            final XmlPullParser in = Xml.newPullParser();
8615            in.setInput(fis, StandardCharsets.UTF_8.name());
8616
8617            int type;
8618            while ((type = in.next()) != END_DOCUMENT) {
8619                final String tag = in.getName();
8620                if (type == START_TAG) {
8621                    if (TAG_URI_GRANT.equals(tag)) {
8622                        final int sourceUserId;
8623                        final int targetUserId;
8624                        final int userHandle = readIntAttribute(in,
8625                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8626                        if (userHandle != UserHandle.USER_NULL) {
8627                            // For backwards compatibility.
8628                            sourceUserId = userHandle;
8629                            targetUserId = userHandle;
8630                        } else {
8631                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8632                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8633                        }
8634                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8635                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8636                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8637                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8638                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8639                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8640
8641                        // Sanity check that provider still belongs to source package
8642                        // Both direct boot aware and unaware packages are fine as we
8643                        // will do filtering at query time to avoid multiple parsing.
8644                        final ProviderInfo pi = getProviderInfoLocked(
8645                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8646                                        | MATCH_DIRECT_BOOT_UNAWARE);
8647                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8648                            int targetUid = -1;
8649                            try {
8650                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8651                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8652                            } catch (RemoteException e) {
8653                            }
8654                            if (targetUid != -1) {
8655                                final UriPermission perm = findOrCreateUriPermissionLocked(
8656                                        sourcePkg, targetPkg, targetUid,
8657                                        new GrantUri(sourceUserId, uri, prefix));
8658                                perm.initPersistedModes(modeFlags, createdTime);
8659                            }
8660                        } else {
8661                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8662                                    + " but instead found " + pi);
8663                        }
8664                    }
8665                }
8666            }
8667        } catch (FileNotFoundException e) {
8668            // Missing grants is okay
8669        } catch (IOException e) {
8670            Slog.wtf(TAG, "Failed reading Uri grants", e);
8671        } catch (XmlPullParserException e) {
8672            Slog.wtf(TAG, "Failed reading Uri grants", e);
8673        } finally {
8674            IoUtils.closeQuietly(fis);
8675        }
8676    }
8677
8678    /**
8679     * @param uri This uri must NOT contain an embedded userId.
8680     * @param userId The userId in which the uri is to be resolved.
8681     */
8682    @Override
8683    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8684        enforceNotIsolatedCaller("takePersistableUriPermission");
8685
8686        Preconditions.checkFlagsArgument(modeFlags,
8687                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8688
8689        synchronized (this) {
8690            final int callingUid = Binder.getCallingUid();
8691            boolean persistChanged = false;
8692            GrantUri grantUri = new GrantUri(userId, uri, false);
8693
8694            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8695                    new GrantUri(userId, uri, false));
8696            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8697                    new GrantUri(userId, uri, true));
8698
8699            final boolean exactValid = (exactPerm != null)
8700                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8701            final boolean prefixValid = (prefixPerm != null)
8702                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8703
8704            if (!(exactValid || prefixValid)) {
8705                throw new SecurityException("No persistable permission grants found for UID "
8706                        + callingUid + " and Uri " + grantUri.toSafeString());
8707            }
8708
8709            if (exactValid) {
8710                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8711            }
8712            if (prefixValid) {
8713                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8714            }
8715
8716            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8717
8718            if (persistChanged) {
8719                schedulePersistUriGrants();
8720            }
8721        }
8722    }
8723
8724    /**
8725     * @param uri This uri must NOT contain an embedded userId.
8726     * @param userId The userId in which the uri is to be resolved.
8727     */
8728    @Override
8729    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8730        enforceNotIsolatedCaller("releasePersistableUriPermission");
8731
8732        Preconditions.checkFlagsArgument(modeFlags,
8733                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8734
8735        synchronized (this) {
8736            final int callingUid = Binder.getCallingUid();
8737            boolean persistChanged = false;
8738
8739            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8740                    new GrantUri(userId, uri, false));
8741            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8742                    new GrantUri(userId, uri, true));
8743            if (exactPerm == null && prefixPerm == null) {
8744                throw new SecurityException("No permission grants found for UID " + callingUid
8745                        + " and Uri " + uri.toSafeString());
8746            }
8747
8748            if (exactPerm != null) {
8749                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8750                removeUriPermissionIfNeededLocked(exactPerm);
8751            }
8752            if (prefixPerm != null) {
8753                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8754                removeUriPermissionIfNeededLocked(prefixPerm);
8755            }
8756
8757            if (persistChanged) {
8758                schedulePersistUriGrants();
8759            }
8760        }
8761    }
8762
8763    /**
8764     * Prune any older {@link UriPermission} for the given UID until outstanding
8765     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8766     *
8767     * @return if any mutations occured that require persisting.
8768     */
8769    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8770        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8771        if (perms == null) return false;
8772        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8773
8774        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8775        for (UriPermission perm : perms.values()) {
8776            if (perm.persistedModeFlags != 0) {
8777                persisted.add(perm);
8778            }
8779        }
8780
8781        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8782        if (trimCount <= 0) return false;
8783
8784        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8785        for (int i = 0; i < trimCount; i++) {
8786            final UriPermission perm = persisted.get(i);
8787
8788            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8789                    "Trimming grant created at " + perm.persistedCreateTime);
8790
8791            perm.releasePersistableModes(~0);
8792            removeUriPermissionIfNeededLocked(perm);
8793        }
8794
8795        return true;
8796    }
8797
8798    @Override
8799    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8800            String packageName, boolean incoming) {
8801        enforceNotIsolatedCaller("getPersistedUriPermissions");
8802        Preconditions.checkNotNull(packageName, "packageName");
8803
8804        final int callingUid = Binder.getCallingUid();
8805        final IPackageManager pm = AppGlobals.getPackageManager();
8806        try {
8807            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8808                    UserHandle.getUserId(callingUid));
8809            if (packageUid != callingUid) {
8810                throw new SecurityException(
8811                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8812            }
8813        } catch (RemoteException e) {
8814            throw new SecurityException("Failed to verify package name ownership");
8815        }
8816
8817        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8818        synchronized (this) {
8819            if (incoming) {
8820                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8821                        callingUid);
8822                if (perms == null) {
8823                    Slog.w(TAG, "No permission grants found for " + packageName);
8824                } else {
8825                    final int userId = UserHandle.getUserId(callingUid);
8826                    Set<String> existingAuthorities = null;
8827
8828                    for (UriPermission perm : perms.values()) {
8829                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8830                            // Is this provider available in the current boot state? If the user
8831                            // is not running and unlocked we check if the provider package exists.
8832                            if (!mUserController.isUserRunningLocked(userId,
8833                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8834                                String authority = perm.uri.uri.getAuthority();
8835                                if (existingAuthorities == null
8836                                        || !existingAuthorities.contains(authority)) {
8837                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8838                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8839                                    if (providerInfo != null) {
8840                                        if (existingAuthorities == null) {
8841                                            existingAuthorities = new ArraySet<>();
8842                                        }
8843                                        existingAuthorities.add(authority);
8844                                    } else {
8845                                        continue;
8846                                    }
8847                                }
8848                            }
8849                            result.add(perm.buildPersistedPublicApiObject());
8850                        }
8851                    }
8852                }
8853            } else {
8854                final int size = mGrantedUriPermissions.size();
8855                for (int i = 0; i < size; i++) {
8856                    final ArrayMap<GrantUri, UriPermission> perms =
8857                            mGrantedUriPermissions.valueAt(i);
8858                    for (UriPermission perm : perms.values()) {
8859                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8860                            result.add(perm.buildPersistedPublicApiObject());
8861                        }
8862                    }
8863                }
8864            }
8865        }
8866        return new ParceledListSlice<android.content.UriPermission>(result);
8867    }
8868
8869    @Override
8870    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8871            String packageName, int userId) {
8872        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8873                "getGrantedUriPermissions");
8874
8875        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8876        synchronized (this) {
8877            final int size = mGrantedUriPermissions.size();
8878            for (int i = 0; i < size; i++) {
8879                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8880                for (UriPermission perm : perms.values()) {
8881                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8882                            && perm.persistedModeFlags != 0) {
8883                        result.add(perm.buildPersistedPublicApiObject());
8884                    }
8885                }
8886            }
8887        }
8888        return new ParceledListSlice<android.content.UriPermission>(result);
8889    }
8890
8891    @Override
8892    public void clearGrantedUriPermissions(String packageName, int userId) {
8893        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8894                "clearGrantedUriPermissions");
8895        removeUriPermissionsForPackageLocked(packageName, userId, true);
8896    }
8897
8898    @Override
8899    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8900        synchronized (this) {
8901            ProcessRecord app =
8902                who != null ? getRecordForAppLocked(who) : null;
8903            if (app == null) return;
8904
8905            Message msg = Message.obtain();
8906            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8907            msg.obj = app;
8908            msg.arg1 = waiting ? 1 : 0;
8909            mUiHandler.sendMessage(msg);
8910        }
8911    }
8912
8913    @Override
8914    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8915        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8916        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8917        outInfo.availMem = Process.getFreeMemory();
8918        outInfo.totalMem = Process.getTotalMemory();
8919        outInfo.threshold = homeAppMem;
8920        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8921        outInfo.hiddenAppThreshold = cachedAppMem;
8922        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8923                ProcessList.SERVICE_ADJ);
8924        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8925                ProcessList.VISIBLE_APP_ADJ);
8926        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8927                ProcessList.FOREGROUND_APP_ADJ);
8928    }
8929
8930    // =========================================================
8931    // TASK MANAGEMENT
8932    // =========================================================
8933
8934    @Override
8935    public List<IAppTask> getAppTasks(String callingPackage) {
8936        int callingUid = Binder.getCallingUid();
8937        long ident = Binder.clearCallingIdentity();
8938
8939        synchronized(this) {
8940            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8941            try {
8942                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8943
8944                final int N = mRecentTasks.size();
8945                for (int i = 0; i < N; i++) {
8946                    TaskRecord tr = mRecentTasks.get(i);
8947                    // Skip tasks that do not match the caller.  We don't need to verify
8948                    // callingPackage, because we are also limiting to callingUid and know
8949                    // that will limit to the correct security sandbox.
8950                    if (tr.effectiveUid != callingUid) {
8951                        continue;
8952                    }
8953                    Intent intent = tr.getBaseIntent();
8954                    if (intent == null ||
8955                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8956                        continue;
8957                    }
8958                    ActivityManager.RecentTaskInfo taskInfo =
8959                            createRecentTaskInfoFromTaskRecord(tr);
8960                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8961                    list.add(taskImpl);
8962                }
8963            } finally {
8964                Binder.restoreCallingIdentity(ident);
8965            }
8966            return list;
8967        }
8968    }
8969
8970    @Override
8971    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8972        final int callingUid = Binder.getCallingUid();
8973        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8974
8975        synchronized(this) {
8976            if (DEBUG_ALL) Slog.v(
8977                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8978
8979            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8980                    callingUid);
8981
8982            // TODO: Improve with MRU list from all ActivityStacks.
8983            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8984        }
8985
8986        return list;
8987    }
8988
8989    /**
8990     * Creates a new RecentTaskInfo from a TaskRecord.
8991     */
8992    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8993        // Update the task description to reflect any changes in the task stack
8994        tr.updateTaskDescription();
8995
8996        // Compose the recent task info
8997        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8998        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8999        rti.persistentId = tr.taskId;
9000        rti.baseIntent = new Intent(tr.getBaseIntent());
9001        rti.origActivity = tr.origActivity;
9002        rti.realActivity = tr.realActivity;
9003        rti.description = tr.lastDescription;
9004        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9005        rti.userId = tr.userId;
9006        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9007        rti.firstActiveTime = tr.firstActiveTime;
9008        rti.lastActiveTime = tr.lastActiveTime;
9009        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9010        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9011        rti.numActivities = 0;
9012        if (tr.mBounds != null) {
9013            rti.bounds = new Rect(tr.mBounds);
9014        }
9015        rti.isDockable = tr.canGoInDockedStack();
9016        rti.resizeMode = tr.mResizeMode;
9017
9018        ActivityRecord base = null;
9019        ActivityRecord top = null;
9020        ActivityRecord tmp;
9021
9022        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9023            tmp = tr.mActivities.get(i);
9024            if (tmp.finishing) {
9025                continue;
9026            }
9027            base = tmp;
9028            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9029                top = base;
9030            }
9031            rti.numActivities++;
9032        }
9033
9034        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9035        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9036
9037        return rti;
9038    }
9039
9040    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9041        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9042                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9043        if (!allowed) {
9044            if (checkPermission(android.Manifest.permission.GET_TASKS,
9045                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9046                // Temporary compatibility: some existing apps on the system image may
9047                // still be requesting the old permission and not switched to the new
9048                // one; if so, we'll still allow them full access.  This means we need
9049                // to see if they are holding the old permission and are a system app.
9050                try {
9051                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9052                        allowed = true;
9053                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9054                                + " is using old GET_TASKS but privileged; allowing");
9055                    }
9056                } catch (RemoteException e) {
9057                }
9058            }
9059        }
9060        if (!allowed) {
9061            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9062                    + " does not hold REAL_GET_TASKS; limiting output");
9063        }
9064        return allowed;
9065    }
9066
9067    @Override
9068    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9069        final int callingUid = Binder.getCallingUid();
9070        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9071                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9072
9073        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9074        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9075        synchronized (this) {
9076            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9077                    callingUid);
9078            final boolean detailed = checkCallingPermission(
9079                    android.Manifest.permission.GET_DETAILED_TASKS)
9080                    == PackageManager.PERMISSION_GRANTED;
9081
9082            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9083                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9084                return Collections.emptyList();
9085            }
9086            mRecentTasks.loadUserRecentsLocked(userId);
9087
9088            final int recentsCount = mRecentTasks.size();
9089            ArrayList<ActivityManager.RecentTaskInfo> res =
9090                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9091
9092            final Set<Integer> includedUsers;
9093            if (includeProfiles) {
9094                includedUsers = mUserController.getProfileIds(userId);
9095            } else {
9096                includedUsers = new HashSet<>();
9097            }
9098            includedUsers.add(Integer.valueOf(userId));
9099
9100            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9101                TaskRecord tr = mRecentTasks.get(i);
9102                // Only add calling user or related users recent tasks
9103                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9104                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9105                    continue;
9106                }
9107
9108                if (tr.realActivitySuspended) {
9109                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9110                    continue;
9111                }
9112
9113                // Return the entry if desired by the caller.  We always return
9114                // the first entry, because callers always expect this to be the
9115                // foreground app.  We may filter others if the caller has
9116                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9117                // we should exclude the entry.
9118
9119                if (i == 0
9120                        || withExcluded
9121                        || (tr.intent == null)
9122                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9123                                == 0)) {
9124                    if (!allowed) {
9125                        // If the caller doesn't have the GET_TASKS permission, then only
9126                        // allow them to see a small subset of tasks -- their own and home.
9127                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9128                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9129                            continue;
9130                        }
9131                    }
9132                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9133                        if (tr.stack != null && tr.stack.isHomeStack()) {
9134                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9135                                    "Skipping, home stack task: " + tr);
9136                            continue;
9137                        }
9138                    }
9139                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9140                        final ActivityStack stack = tr.stack;
9141                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9142                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9143                                    "Skipping, top task in docked stack: " + tr);
9144                            continue;
9145                        }
9146                    }
9147                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9148                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9149                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9150                                    "Skipping, pinned stack task: " + tr);
9151                            continue;
9152                        }
9153                    }
9154                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9155                        // Don't include auto remove tasks that are finished or finishing.
9156                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9157                                "Skipping, auto-remove without activity: " + tr);
9158                        continue;
9159                    }
9160                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9161                            && !tr.isAvailable) {
9162                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9163                                "Skipping, unavail real act: " + tr);
9164                        continue;
9165                    }
9166
9167                    if (!tr.mUserSetupComplete) {
9168                        // Don't include task launched while user is not done setting-up.
9169                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                "Skipping, user setup not complete: " + tr);
9171                        continue;
9172                    }
9173
9174                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9175                    if (!detailed) {
9176                        rti.baseIntent.replaceExtras((Bundle)null);
9177                    }
9178
9179                    res.add(rti);
9180                    maxNum--;
9181                }
9182            }
9183            return res;
9184        }
9185    }
9186
9187    @Override
9188    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9189        synchronized (this) {
9190            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9191                    "getTaskThumbnail()");
9192            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9193                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9194            if (tr != null) {
9195                return tr.getTaskThumbnailLocked();
9196            }
9197        }
9198        return null;
9199    }
9200
9201    @Override
9202    public int addAppTask(IBinder activityToken, Intent intent,
9203            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9204        final int callingUid = Binder.getCallingUid();
9205        final long callingIdent = Binder.clearCallingIdentity();
9206
9207        try {
9208            synchronized (this) {
9209                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9210                if (r == null) {
9211                    throw new IllegalArgumentException("Activity does not exist; token="
9212                            + activityToken);
9213                }
9214                ComponentName comp = intent.getComponent();
9215                if (comp == null) {
9216                    throw new IllegalArgumentException("Intent " + intent
9217                            + " must specify explicit component");
9218                }
9219                if (thumbnail.getWidth() != mThumbnailWidth
9220                        || thumbnail.getHeight() != mThumbnailHeight) {
9221                    throw new IllegalArgumentException("Bad thumbnail size: got "
9222                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9223                            + mThumbnailWidth + "x" + mThumbnailHeight);
9224                }
9225                if (intent.getSelector() != null) {
9226                    intent.setSelector(null);
9227                }
9228                if (intent.getSourceBounds() != null) {
9229                    intent.setSourceBounds(null);
9230                }
9231                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9232                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9233                        // The caller has added this as an auto-remove task...  that makes no
9234                        // sense, so turn off auto-remove.
9235                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9236                    }
9237                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9238                    // Must be a new task.
9239                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9240                }
9241                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9242                    mLastAddedTaskActivity = null;
9243                }
9244                ActivityInfo ainfo = mLastAddedTaskActivity;
9245                if (ainfo == null) {
9246                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9247                            comp, 0, UserHandle.getUserId(callingUid));
9248                    if (ainfo.applicationInfo.uid != callingUid) {
9249                        throw new SecurityException(
9250                                "Can't add task for another application: target uid="
9251                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9252                    }
9253                }
9254
9255                // Use the full screen as the context for the task thumbnail
9256                final Point displaySize = new Point();
9257                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9258                r.task.stack.getDisplaySize(displaySize);
9259                thumbnailInfo.taskWidth = displaySize.x;
9260                thumbnailInfo.taskHeight = displaySize.y;
9261                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9262
9263                TaskRecord task = new TaskRecord(this,
9264                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9265                        ainfo, intent, description, thumbnailInfo);
9266
9267                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9268                if (trimIdx >= 0) {
9269                    // If this would have caused a trim, then we'll abort because that
9270                    // means it would be added at the end of the list but then just removed.
9271                    return INVALID_TASK_ID;
9272                }
9273
9274                final int N = mRecentTasks.size();
9275                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9276                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9277                    tr.removedFromRecents();
9278                }
9279
9280                task.inRecents = true;
9281                mRecentTasks.add(task);
9282                r.task.stack.addTask(task, false, "addAppTask");
9283
9284                task.setLastThumbnailLocked(thumbnail);
9285                task.freeLastThumbnail();
9286
9287                return task.taskId;
9288            }
9289        } finally {
9290            Binder.restoreCallingIdentity(callingIdent);
9291        }
9292    }
9293
9294    @Override
9295    public Point getAppTaskThumbnailSize() {
9296        synchronized (this) {
9297            return new Point(mThumbnailWidth,  mThumbnailHeight);
9298        }
9299    }
9300
9301    @Override
9302    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9303        synchronized (this) {
9304            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9305            if (r != null) {
9306                r.setTaskDescription(td);
9307                r.task.updateTaskDescription();
9308            }
9309        }
9310    }
9311
9312    @Override
9313    public void setTaskResizeable(int taskId, int resizeableMode) {
9314        synchronized (this) {
9315            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9316                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9317            if (task == null) {
9318                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9319                return;
9320            }
9321            if (task.mResizeMode != resizeableMode) {
9322                task.mResizeMode = resizeableMode;
9323                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9324                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9325                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9326            }
9327        }
9328    }
9329
9330    @Override
9331    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9332        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9333        long ident = Binder.clearCallingIdentity();
9334        try {
9335            synchronized (this) {
9336                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9337                if (task == null) {
9338                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9339                    return;
9340                }
9341                int stackId = task.stack.mStackId;
9342                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9343                // in crop windows resize mode or if the task size is affected by the docked stack
9344                // changing size. No need to update configuration.
9345                if (bounds != null && task.inCropWindowsResizeMode()
9346                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9347                    mWindowManager.scrollTask(task.taskId, bounds);
9348                    return;
9349                }
9350
9351                // Place the task in the right stack if it isn't there already based on
9352                // the requested bounds.
9353                // The stack transition logic is:
9354                // - a null bounds on a freeform task moves that task to fullscreen
9355                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9356                //   that task to freeform
9357                // - otherwise the task is not moved
9358                if (!StackId.isTaskResizeAllowed(stackId)) {
9359                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9360                }
9361                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9362                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9363                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9364                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9365                }
9366                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9367                if (stackId != task.stack.mStackId) {
9368                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9369                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9370                    preserveWindow = false;
9371                }
9372
9373                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9374                        false /* deferResume */);
9375            }
9376        } finally {
9377            Binder.restoreCallingIdentity(ident);
9378        }
9379    }
9380
9381    @Override
9382    public Rect getTaskBounds(int taskId) {
9383        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9384        long ident = Binder.clearCallingIdentity();
9385        Rect rect = new Rect();
9386        try {
9387            synchronized (this) {
9388                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9389                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9390                if (task == null) {
9391                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9392                    return rect;
9393                }
9394                if (task.stack != null) {
9395                    // Return the bounds from window manager since it will be adjusted for various
9396                    // things like the presense of a docked stack for tasks that aren't resizeable.
9397                    mWindowManager.getTaskBounds(task.taskId, rect);
9398                } else {
9399                    // Task isn't in window manager yet since it isn't associated with a stack.
9400                    // Return the persist value from activity manager
9401                    if (task.mBounds != null) {
9402                        rect.set(task.mBounds);
9403                    } else if (task.mLastNonFullscreenBounds != null) {
9404                        rect.set(task.mLastNonFullscreenBounds);
9405                    }
9406                }
9407            }
9408        } finally {
9409            Binder.restoreCallingIdentity(ident);
9410        }
9411        return rect;
9412    }
9413
9414    @Override
9415    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9416        if (userId != UserHandle.getCallingUserId()) {
9417            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9418                    "getTaskDescriptionIcon");
9419        }
9420        final File passedIconFile = new File(filePath);
9421        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9422                passedIconFile.getName());
9423        if (!legitIconFile.getPath().equals(filePath)
9424                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9425            throw new IllegalArgumentException("Bad file path: " + filePath
9426                    + " passed for userId " + userId);
9427        }
9428        return mRecentTasks.getTaskDescriptionIcon(filePath);
9429    }
9430
9431    @Override
9432    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9433            throws RemoteException {
9434        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9435                opts.getCustomInPlaceResId() == 0) {
9436            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9437                    "with valid animation");
9438        }
9439        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9440        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9441                opts.getCustomInPlaceResId());
9442        mWindowManager.executeAppTransition();
9443    }
9444
9445    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9446            boolean removeFromRecents) {
9447        if (removeFromRecents) {
9448            mRecentTasks.remove(tr);
9449            tr.removedFromRecents();
9450        }
9451        ComponentName component = tr.getBaseIntent().getComponent();
9452        if (component == null) {
9453            Slog.w(TAG, "No component for base intent of task: " + tr);
9454            return;
9455        }
9456
9457        // Find any running services associated with this app and stop if needed.
9458        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9459
9460        if (!killProcess) {
9461            return;
9462        }
9463
9464        // Determine if the process(es) for this task should be killed.
9465        final String pkg = component.getPackageName();
9466        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9467        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9468        for (int i = 0; i < pmap.size(); i++) {
9469
9470            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9471            for (int j = 0; j < uids.size(); j++) {
9472                ProcessRecord proc = uids.valueAt(j);
9473                if (proc.userId != tr.userId) {
9474                    // Don't kill process for a different user.
9475                    continue;
9476                }
9477                if (proc == mHomeProcess) {
9478                    // Don't kill the home process along with tasks from the same package.
9479                    continue;
9480                }
9481                if (!proc.pkgList.containsKey(pkg)) {
9482                    // Don't kill process that is not associated with this task.
9483                    continue;
9484                }
9485
9486                for (int k = 0; k < proc.activities.size(); k++) {
9487                    TaskRecord otherTask = proc.activities.get(k).task;
9488                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9489                        // Don't kill process(es) that has an activity in a different task that is
9490                        // also in recents.
9491                        return;
9492                    }
9493                }
9494
9495                if (proc.foregroundServices) {
9496                    // Don't kill process(es) with foreground service.
9497                    return;
9498                }
9499
9500                // Add process to kill list.
9501                procsToKill.add(proc);
9502            }
9503        }
9504
9505        // Kill the running processes.
9506        for (int i = 0; i < procsToKill.size(); i++) {
9507            ProcessRecord pr = procsToKill.get(i);
9508            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9509                    && pr.curReceiver == null) {
9510                pr.kill("remove task", true);
9511            } else {
9512                // We delay killing processes that are not in the background or running a receiver.
9513                pr.waitingToKill = "remove task";
9514            }
9515        }
9516    }
9517
9518    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9519        // Remove all tasks with activities in the specified package from the list of recent tasks
9520        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9521            TaskRecord tr = mRecentTasks.get(i);
9522            if (tr.userId != userId) continue;
9523
9524            ComponentName cn = tr.intent.getComponent();
9525            if (cn != null && cn.getPackageName().equals(packageName)) {
9526                // If the package name matches, remove the task.
9527                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9528            }
9529        }
9530    }
9531
9532    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9533            int userId) {
9534
9535        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9536            TaskRecord tr = mRecentTasks.get(i);
9537            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9538                continue;
9539            }
9540
9541            ComponentName cn = tr.intent.getComponent();
9542            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9543                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9544            if (sameComponent) {
9545                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9546            }
9547        }
9548    }
9549
9550    /**
9551     * Removes the task with the specified task id.
9552     *
9553     * @param taskId Identifier of the task to be removed.
9554     * @param killProcess Kill any process associated with the task if possible.
9555     * @param removeFromRecents Whether to also remove the task from recents.
9556     * @return Returns true if the given task was found and removed.
9557     */
9558    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9559            boolean removeFromRecents) {
9560        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9561                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9562        if (tr != null) {
9563            tr.removeTaskActivitiesLocked();
9564            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9565            if (tr.isPersistable) {
9566                notifyTaskPersisterLocked(null, true);
9567            }
9568            return true;
9569        }
9570        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9571        return false;
9572    }
9573
9574    @Override
9575    public void removeStack(int stackId) {
9576        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9577        if (stackId == HOME_STACK_ID) {
9578            throw new IllegalArgumentException("Removing home stack is not allowed.");
9579        }
9580
9581        synchronized (this) {
9582            final long ident = Binder.clearCallingIdentity();
9583            try {
9584                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9585                if (stack == null) {
9586                    return;
9587                }
9588                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9589                for (int i = tasks.size() - 1; i >= 0; i--) {
9590                    removeTaskByIdLocked(
9591                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9592                }
9593            } finally {
9594                Binder.restoreCallingIdentity(ident);
9595            }
9596        }
9597    }
9598
9599    @Override
9600    public boolean removeTask(int taskId) {
9601        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9602        synchronized (this) {
9603            final long ident = Binder.clearCallingIdentity();
9604            try {
9605                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9606            } finally {
9607                Binder.restoreCallingIdentity(ident);
9608            }
9609        }
9610    }
9611
9612    /**
9613     * TODO: Add mController hook
9614     */
9615    @Override
9616    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9617        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9618
9619        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9620        synchronized(this) {
9621            moveTaskToFrontLocked(taskId, flags, bOptions);
9622        }
9623    }
9624
9625    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9626        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9627
9628        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9629                Binder.getCallingUid(), -1, -1, "Task to front")) {
9630            ActivityOptions.abort(options);
9631            return;
9632        }
9633        final long origId = Binder.clearCallingIdentity();
9634        try {
9635            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9636            if (task == null) {
9637                Slog.d(TAG, "Could not find task for id: "+ taskId);
9638                return;
9639            }
9640            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9641                mStackSupervisor.showLockTaskToast();
9642                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9643                return;
9644            }
9645            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9646            if (prev != null && prev.isRecentsActivity()) {
9647                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9648            }
9649            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9650                    false /* forceNonResizable */);
9651        } finally {
9652            Binder.restoreCallingIdentity(origId);
9653        }
9654        ActivityOptions.abort(options);
9655    }
9656
9657    /**
9658     * Moves an activity, and all of the other activities within the same task, to the bottom
9659     * of the history stack.  The activity's order within the task is unchanged.
9660     *
9661     * @param token A reference to the activity we wish to move
9662     * @param nonRoot If false then this only works if the activity is the root
9663     *                of a task; if true it will work for any activity in a task.
9664     * @return Returns true if the move completed, false if not.
9665     */
9666    @Override
9667    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9668        enforceNotIsolatedCaller("moveActivityTaskToBack");
9669        synchronized(this) {
9670            final long origId = Binder.clearCallingIdentity();
9671            try {
9672                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9673                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9674                if (task != null) {
9675                    if (mStackSupervisor.isLockedTask(task)) {
9676                        mStackSupervisor.showLockTaskToast();
9677                        return false;
9678                    }
9679                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9680                }
9681            } finally {
9682                Binder.restoreCallingIdentity(origId);
9683            }
9684        }
9685        return false;
9686    }
9687
9688    @Override
9689    public void moveTaskBackwards(int task) {
9690        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9691                "moveTaskBackwards()");
9692
9693        synchronized(this) {
9694            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9695                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9696                return;
9697            }
9698            final long origId = Binder.clearCallingIdentity();
9699            moveTaskBackwardsLocked(task);
9700            Binder.restoreCallingIdentity(origId);
9701        }
9702    }
9703
9704    private final void moveTaskBackwardsLocked(int task) {
9705        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9706    }
9707
9708    @Override
9709    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9710            IActivityContainerCallback callback) throws RemoteException {
9711        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9712        synchronized (this) {
9713            if (parentActivityToken == null) {
9714                throw new IllegalArgumentException("parent token must not be null");
9715            }
9716            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9717            if (r == null) {
9718                return null;
9719            }
9720            if (callback == null) {
9721                throw new IllegalArgumentException("callback must not be null");
9722            }
9723            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9724        }
9725    }
9726
9727    @Override
9728    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9730        synchronized (this) {
9731            mStackSupervisor.deleteActivityContainer(container);
9732        }
9733    }
9734
9735    @Override
9736    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9738        synchronized (this) {
9739            final int stackId = mStackSupervisor.getNextStackId();
9740            final ActivityStack stack =
9741                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9742            if (stack == null) {
9743                return null;
9744            }
9745            return stack.mActivityContainer;
9746        }
9747    }
9748
9749    @Override
9750    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9751        synchronized (this) {
9752            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9753            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9754                return stack.mActivityContainer.getDisplayId();
9755            }
9756            return Display.DEFAULT_DISPLAY;
9757        }
9758    }
9759
9760    @Override
9761    public int getActivityStackId(IBinder token) throws RemoteException {
9762        synchronized (this) {
9763            ActivityStack stack = ActivityRecord.getStackLocked(token);
9764            if (stack == null) {
9765                return INVALID_STACK_ID;
9766            }
9767            return stack.mStackId;
9768        }
9769    }
9770
9771    @Override
9772    public void exitFreeformMode(IBinder token) throws RemoteException {
9773        synchronized (this) {
9774            long ident = Binder.clearCallingIdentity();
9775            try {
9776                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9777                if (r == null) {
9778                    throw new IllegalArgumentException(
9779                            "exitFreeformMode: No activity record matching token=" + token);
9780                }
9781                final ActivityStack stack = r.getStackLocked(token);
9782                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9783                    throw new IllegalStateException(
9784                            "exitFreeformMode: You can only go fullscreen from freeform.");
9785                }
9786                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9787                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9788                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9789            } finally {
9790                Binder.restoreCallingIdentity(ident);
9791            }
9792        }
9793    }
9794
9795    @Override
9796    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9797        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9798        if (stackId == HOME_STACK_ID) {
9799            throw new IllegalArgumentException(
9800                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9801        }
9802        synchronized (this) {
9803            long ident = Binder.clearCallingIdentity();
9804            try {
9805                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9806                        + " to stackId=" + stackId + " toTop=" + toTop);
9807                if (stackId == DOCKED_STACK_ID) {
9808                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9809                            null /* initialBounds */);
9810                }
9811                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9812                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9813                if (result && stackId == DOCKED_STACK_ID) {
9814                    // If task moved to docked stack - show recents if needed.
9815                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9816                            "moveTaskToDockedStack");
9817                }
9818            } finally {
9819                Binder.restoreCallingIdentity(ident);
9820            }
9821        }
9822    }
9823
9824    @Override
9825    public void swapDockedAndFullscreenStack() throws RemoteException {
9826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9827        synchronized (this) {
9828            long ident = Binder.clearCallingIdentity();
9829            try {
9830                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9831                        FULLSCREEN_WORKSPACE_STACK_ID);
9832                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9833                        : null;
9834                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9835                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9836                        : null;
9837                if (topTask == null || tasks == null || tasks.size() == 0) {
9838                    Slog.w(TAG,
9839                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9840                    return;
9841                }
9842
9843                // TODO: App transition
9844                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9845
9846                // Defer the resume so resume/pausing while moving stacks is dangerous.
9847                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9848                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9849                        ANIMATE, true /* deferResume */);
9850                final int size = tasks.size();
9851                for (int i = 0; i < size; i++) {
9852                    final int id = tasks.get(i).taskId;
9853                    if (id == topTask.taskId) {
9854                        continue;
9855                    }
9856                    mStackSupervisor.moveTaskToStackLocked(id,
9857                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9858                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9859                }
9860
9861                // Because we deferred the resume, to avoid conflicts with stack switches while
9862                // resuming, we need to do it after all the tasks are moved.
9863                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9864                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9865
9866                mWindowManager.executeAppTransition();
9867            } finally {
9868                Binder.restoreCallingIdentity(ident);
9869            }
9870        }
9871    }
9872
9873    /**
9874     * Moves the input task to the docked stack.
9875     *
9876     * @param taskId Id of task to move.
9877     * @param createMode The mode the docked stack should be created in if it doesn't exist
9878     *                   already. See
9879     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9880     *                   and
9881     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9882     * @param toTop If the task and stack should be moved to the top.
9883     * @param animate Whether we should play an animation for the moving the task
9884     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9885     *                      docked stack. Pass {@code null} to use default bounds.
9886     */
9887    @Override
9888    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9889            Rect initialBounds, boolean moveHomeStackFront) {
9890        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9891        synchronized (this) {
9892            long ident = Binder.clearCallingIdentity();
9893            try {
9894                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9895                        + " to createMode=" + createMode + " toTop=" + toTop);
9896                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9897                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9898                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9899                        animate, DEFER_RESUME);
9900                if (moved) {
9901                    if (moveHomeStackFront) {
9902                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9903                    }
9904                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9905                }
9906                return moved;
9907            } finally {
9908                Binder.restoreCallingIdentity(ident);
9909            }
9910        }
9911    }
9912
9913    /**
9914     * Moves the top activity in the input stackId to the pinned stack.
9915     *
9916     * @param stackId Id of stack to move the top activity to pinned stack.
9917     * @param bounds Bounds to use for pinned stack.
9918     *
9919     * @return True if the top activity of the input stack was successfully moved to the pinned
9920     *          stack.
9921     */
9922    @Override
9923    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9924        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9925        synchronized (this) {
9926            if (!mSupportsPictureInPicture) {
9927                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9928                        + "Device doesn't support picture-in-pciture mode");
9929            }
9930
9931            long ident = Binder.clearCallingIdentity();
9932            try {
9933                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9934            } finally {
9935                Binder.restoreCallingIdentity(ident);
9936            }
9937        }
9938    }
9939
9940    @Override
9941    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9942            boolean preserveWindows, boolean animate, int animationDuration) {
9943        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9944        long ident = Binder.clearCallingIdentity();
9945        try {
9946            synchronized (this) {
9947                if (animate) {
9948                    if (stackId == PINNED_STACK_ID) {
9949                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9950                    } else {
9951                        throw new IllegalArgumentException("Stack: " + stackId
9952                                + " doesn't support animated resize.");
9953                    }
9954                } else {
9955                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9956                            null /* tempTaskInsetBounds */, preserveWindows,
9957                            allowResizeInDockedMode, !DEFER_RESUME);
9958                }
9959            }
9960        } finally {
9961            Binder.restoreCallingIdentity(ident);
9962        }
9963    }
9964
9965    @Override
9966    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9967            Rect tempDockedTaskInsetBounds,
9968            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9970                "resizeDockedStack()");
9971        long ident = Binder.clearCallingIdentity();
9972        try {
9973            synchronized (this) {
9974                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9975                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9976                        PRESERVE_WINDOWS);
9977            }
9978        } finally {
9979            Binder.restoreCallingIdentity(ident);
9980        }
9981    }
9982
9983    @Override
9984    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9985        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9986                "resizePinnedStack()");
9987        final long ident = Binder.clearCallingIdentity();
9988        try {
9989            synchronized (this) {
9990                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9991            }
9992        } finally {
9993            Binder.restoreCallingIdentity(ident);
9994        }
9995    }
9996
9997    @Override
9998    public void positionTaskInStack(int taskId, int stackId, int position) {
9999        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10000        if (stackId == HOME_STACK_ID) {
10001            throw new IllegalArgumentException(
10002                    "positionTaskInStack: Attempt to change the position of task "
10003                    + taskId + " in/to home stack");
10004        }
10005        synchronized (this) {
10006            long ident = Binder.clearCallingIdentity();
10007            try {
10008                if (DEBUG_STACK) Slog.d(TAG_STACK,
10009                        "positionTaskInStack: positioning task=" + taskId
10010                        + " in stackId=" + stackId + " at position=" + position);
10011                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10012            } finally {
10013                Binder.restoreCallingIdentity(ident);
10014            }
10015        }
10016    }
10017
10018    @Override
10019    public List<StackInfo> getAllStackInfos() {
10020        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10021        long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                return mStackSupervisor.getAllStackInfosLocked();
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public StackInfo getStackInfo(int stackId) {
10033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10034        long ident = Binder.clearCallingIdentity();
10035        try {
10036            synchronized (this) {
10037                return mStackSupervisor.getStackInfoLocked(stackId);
10038            }
10039        } finally {
10040            Binder.restoreCallingIdentity(ident);
10041        }
10042    }
10043
10044    @Override
10045    public boolean isInHomeStack(int taskId) {
10046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10047        long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10051                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10052                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10053            }
10054        } finally {
10055            Binder.restoreCallingIdentity(ident);
10056        }
10057    }
10058
10059    @Override
10060    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10061        synchronized(this) {
10062            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10063        }
10064    }
10065
10066    @Override
10067    public void updateDeviceOwner(String packageName) {
10068        final int callingUid = Binder.getCallingUid();
10069        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10070            throw new SecurityException("updateDeviceOwner called from non-system process");
10071        }
10072        synchronized (this) {
10073            mDeviceOwnerName = packageName;
10074        }
10075    }
10076
10077    @Override
10078    public void updateLockTaskPackages(int userId, String[] packages) {
10079        final int callingUid = Binder.getCallingUid();
10080        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10081            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10082                    "updateLockTaskPackages()");
10083        }
10084        synchronized (this) {
10085            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10086                    Arrays.toString(packages));
10087            mLockTaskPackages.put(userId, packages);
10088            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10089        }
10090    }
10091
10092
10093    void startLockTaskModeLocked(TaskRecord task) {
10094        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10095        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10096            return;
10097        }
10098
10099        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10100        // is initiated by system after the pinning request was shown and locked mode is initiated
10101        // by an authorized app directly
10102        final int callingUid = Binder.getCallingUid();
10103        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10104        long ident = Binder.clearCallingIdentity();
10105        try {
10106            if (!isSystemInitiated) {
10107                task.mLockTaskUid = callingUid;
10108                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10109                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10110                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10111                    StatusBarManagerInternal statusBarManager =
10112                            LocalServices.getService(StatusBarManagerInternal.class);
10113                    if (statusBarManager != null) {
10114                        statusBarManager.showScreenPinningRequest(task.taskId);
10115                    }
10116                    return;
10117                }
10118
10119                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10120                if (stack == null || task != stack.topTask()) {
10121                    throw new IllegalArgumentException("Invalid task, not in foreground");
10122                }
10123            }
10124            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10125                    "Locking fully");
10126            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10127                    ActivityManager.LOCK_TASK_MODE_PINNED :
10128                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10129                    "startLockTask", true);
10130        } finally {
10131            Binder.restoreCallingIdentity(ident);
10132        }
10133    }
10134
10135    @Override
10136    public void startLockTaskMode(int taskId) {
10137        synchronized (this) {
10138            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10139            if (task != null) {
10140                startLockTaskModeLocked(task);
10141            }
10142        }
10143    }
10144
10145    @Override
10146    public void startLockTaskMode(IBinder token) {
10147        synchronized (this) {
10148            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10149            if (r == null) {
10150                return;
10151            }
10152            final TaskRecord task = r.task;
10153            if (task != null) {
10154                startLockTaskModeLocked(task);
10155            }
10156        }
10157    }
10158
10159    @Override
10160    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10162        // This makes inner call to look as if it was initiated by system.
10163        long ident = Binder.clearCallingIdentity();
10164        try {
10165            synchronized (this) {
10166                startLockTaskMode(taskId);
10167            }
10168        } finally {
10169            Binder.restoreCallingIdentity(ident);
10170        }
10171    }
10172
10173    @Override
10174    public void stopLockTaskMode() {
10175        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10176        if (lockTask == null) {
10177            // Our work here is done.
10178            return;
10179        }
10180
10181        final int callingUid = Binder.getCallingUid();
10182        final int lockTaskUid = lockTask.mLockTaskUid;
10183        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10184        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10185            // Done.
10186            return;
10187        } else {
10188            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10189            // It is possible lockTaskMode was started by the system process because
10190            // android:lockTaskMode is set to a locking value in the application manifest
10191            // instead of the app calling startLockTaskMode. In this case
10192            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10193            // {@link TaskRecord.effectiveUid} instead. Also caller with
10194            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10195            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10196                    && callingUid != lockTaskUid
10197                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10198                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10199                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10200            }
10201        }
10202        long ident = Binder.clearCallingIdentity();
10203        try {
10204            Log.d(TAG, "stopLockTaskMode");
10205            // Stop lock task
10206            synchronized (this) {
10207                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10208                        "stopLockTask", true);
10209            }
10210            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10211            if (tm != null) {
10212                tm.showInCallScreen(false);
10213            }
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    /**
10220     * This API should be called by SystemUI only when user perform certain action to dismiss
10221     * lock task mode. We should only dismiss pinned lock task mode in this case.
10222     */
10223    @Override
10224    public void stopSystemLockTaskMode() throws RemoteException {
10225        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10226            stopLockTaskMode();
10227        } else {
10228            mStackSupervisor.showLockTaskToast();
10229        }
10230    }
10231
10232    @Override
10233    public boolean isInLockTaskMode() {
10234        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10235    }
10236
10237    @Override
10238    public int getLockTaskModeState() {
10239        synchronized (this) {
10240            return mStackSupervisor.getLockTaskModeState();
10241        }
10242    }
10243
10244    @Override
10245    public void showLockTaskEscapeMessage(IBinder token) {
10246        synchronized (this) {
10247            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10248            if (r == null) {
10249                return;
10250            }
10251            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10252        }
10253    }
10254
10255    // =========================================================
10256    // CONTENT PROVIDERS
10257    // =========================================================
10258
10259    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10260        List<ProviderInfo> providers = null;
10261        try {
10262            providers = AppGlobals.getPackageManager()
10263                    .queryContentProviders(app.processName, app.uid,
10264                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10265                                    | MATCH_DEBUG_TRIAGED_MISSING)
10266                    .getList();
10267        } catch (RemoteException ex) {
10268        }
10269        if (DEBUG_MU) Slog.v(TAG_MU,
10270                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10271        int userId = app.userId;
10272        if (providers != null) {
10273            int N = providers.size();
10274            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10275            for (int i=0; i<N; i++) {
10276                // TODO: keep logic in sync with installEncryptionUnawareProviders
10277                ProviderInfo cpi =
10278                    (ProviderInfo)providers.get(i);
10279                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10280                        cpi.name, cpi.flags);
10281                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10282                    // This is a singleton provider, but a user besides the
10283                    // default user is asking to initialize a process it runs
10284                    // in...  well, no, it doesn't actually run in this process,
10285                    // it runs in the process of the default user.  Get rid of it.
10286                    providers.remove(i);
10287                    N--;
10288                    i--;
10289                    continue;
10290                }
10291
10292                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10293                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10294                if (cpr == null) {
10295                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10296                    mProviderMap.putProviderByClass(comp, cpr);
10297                }
10298                if (DEBUG_MU) Slog.v(TAG_MU,
10299                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10300                app.pubProviders.put(cpi.name, cpr);
10301                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10302                    // Don't add this if it is a platform component that is marked
10303                    // to run in multiple processes, because this is actually
10304                    // part of the framework so doesn't make sense to track as a
10305                    // separate apk in the process.
10306                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10307                            mProcessStats);
10308                }
10309                notifyPackageUse(cpi.applicationInfo.packageName,
10310                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10311            }
10312        }
10313        return providers;
10314    }
10315
10316    /**
10317     * Check if {@link ProcessRecord} has a possible chance at accessing the
10318     * given {@link ProviderInfo}. Final permission checking is always done
10319     * in {@link ContentProvider}.
10320     */
10321    private final String checkContentProviderPermissionLocked(
10322            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10323        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10324        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10325        boolean checkedGrants = false;
10326        if (checkUser) {
10327            // Looking for cross-user grants before enforcing the typical cross-users permissions
10328            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10329            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10330                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10331                    return null;
10332                }
10333                checkedGrants = true;
10334            }
10335            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10336                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10337            if (userId != tmpTargetUserId) {
10338                // When we actually went to determine the final targer user ID, this ended
10339                // up different than our initial check for the authority.  This is because
10340                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10341                // SELF.  So we need to re-check the grants again.
10342                checkedGrants = false;
10343            }
10344        }
10345        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10346                cpi.applicationInfo.uid, cpi.exported)
10347                == PackageManager.PERMISSION_GRANTED) {
10348            return null;
10349        }
10350        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10351                cpi.applicationInfo.uid, cpi.exported)
10352                == PackageManager.PERMISSION_GRANTED) {
10353            return null;
10354        }
10355
10356        PathPermission[] pps = cpi.pathPermissions;
10357        if (pps != null) {
10358            int i = pps.length;
10359            while (i > 0) {
10360                i--;
10361                PathPermission pp = pps[i];
10362                String pprperm = pp.getReadPermission();
10363                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10364                        cpi.applicationInfo.uid, cpi.exported)
10365                        == PackageManager.PERMISSION_GRANTED) {
10366                    return null;
10367                }
10368                String ppwperm = pp.getWritePermission();
10369                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10370                        cpi.applicationInfo.uid, cpi.exported)
10371                        == PackageManager.PERMISSION_GRANTED) {
10372                    return null;
10373                }
10374            }
10375        }
10376        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10377            return null;
10378        }
10379
10380        String msg;
10381        if (!cpi.exported) {
10382            msg = "Permission Denial: opening provider " + cpi.name
10383                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10384                    + ", uid=" + callingUid + ") that is not exported from uid "
10385                    + cpi.applicationInfo.uid;
10386        } else {
10387            msg = "Permission Denial: opening provider " + cpi.name
10388                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10389                    + ", uid=" + callingUid + ") requires "
10390                    + cpi.readPermission + " or " + cpi.writePermission;
10391        }
10392        Slog.w(TAG, msg);
10393        return msg;
10394    }
10395
10396    /**
10397     * Returns if the ContentProvider has granted a uri to callingUid
10398     */
10399    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10400        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10401        if (perms != null) {
10402            for (int i=perms.size()-1; i>=0; i--) {
10403                GrantUri grantUri = perms.keyAt(i);
10404                if (grantUri.sourceUserId == userId || !checkUser) {
10405                    if (matchesProvider(grantUri.uri, cpi)) {
10406                        return true;
10407                    }
10408                }
10409            }
10410        }
10411        return false;
10412    }
10413
10414    /**
10415     * Returns true if the uri authority is one of the authorities specified in the provider.
10416     */
10417    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10418        String uriAuth = uri.getAuthority();
10419        String cpiAuth = cpi.authority;
10420        if (cpiAuth.indexOf(';') == -1) {
10421            return cpiAuth.equals(uriAuth);
10422        }
10423        String[] cpiAuths = cpiAuth.split(";");
10424        int length = cpiAuths.length;
10425        for (int i = 0; i < length; i++) {
10426            if (cpiAuths[i].equals(uriAuth)) return true;
10427        }
10428        return false;
10429    }
10430
10431    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10432            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433        if (r != null) {
10434            for (int i=0; i<r.conProviders.size(); i++) {
10435                ContentProviderConnection conn = r.conProviders.get(i);
10436                if (conn.provider == cpr) {
10437                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10438                            "Adding provider requested by "
10439                            + r.processName + " from process "
10440                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10441                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10442                    if (stable) {
10443                        conn.stableCount++;
10444                        conn.numStableIncs++;
10445                    } else {
10446                        conn.unstableCount++;
10447                        conn.numUnstableIncs++;
10448                    }
10449                    return conn;
10450                }
10451            }
10452            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10453            if (stable) {
10454                conn.stableCount = 1;
10455                conn.numStableIncs = 1;
10456            } else {
10457                conn.unstableCount = 1;
10458                conn.numUnstableIncs = 1;
10459            }
10460            cpr.connections.add(conn);
10461            r.conProviders.add(conn);
10462            startAssociationLocked(r.uid, r.processName, r.curProcState,
10463                    cpr.uid, cpr.name, cpr.info.processName);
10464            return conn;
10465        }
10466        cpr.addExternalProcessHandleLocked(externalProcessToken);
10467        return null;
10468    }
10469
10470    boolean decProviderCountLocked(ContentProviderConnection conn,
10471            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10472        if (conn != null) {
10473            cpr = conn.provider;
10474            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10475                    "Removing provider requested by "
10476                    + conn.client.processName + " from process "
10477                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10478                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10479            if (stable) {
10480                conn.stableCount--;
10481            } else {
10482                conn.unstableCount--;
10483            }
10484            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10485                cpr.connections.remove(conn);
10486                conn.client.conProviders.remove(conn);
10487                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10488                    // The client is more important than last activity -- note the time this
10489                    // is happening, so we keep the old provider process around a bit as last
10490                    // activity to avoid thrashing it.
10491                    if (cpr.proc != null) {
10492                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10493                    }
10494                }
10495                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10496                return true;
10497            }
10498            return false;
10499        }
10500        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10501        return false;
10502    }
10503
10504    private void checkTime(long startTime, String where) {
10505        long now = SystemClock.uptimeMillis();
10506        if ((now-startTime) > 50) {
10507            // If we are taking more than 50ms, log about it.
10508            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10509        }
10510    }
10511
10512    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10513            String name, IBinder token, boolean stable, int userId) {
10514        ContentProviderRecord cpr;
10515        ContentProviderConnection conn = null;
10516        ProviderInfo cpi = null;
10517
10518        synchronized(this) {
10519            long startTime = SystemClock.uptimeMillis();
10520
10521            ProcessRecord r = null;
10522            if (caller != null) {
10523                r = getRecordForAppLocked(caller);
10524                if (r == null) {
10525                    throw new SecurityException(
10526                            "Unable to find app for caller " + caller
10527                          + " (pid=" + Binder.getCallingPid()
10528                          + ") when getting content provider " + name);
10529                }
10530            }
10531
10532            boolean checkCrossUser = true;
10533
10534            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10535
10536            // First check if this content provider has been published...
10537            cpr = mProviderMap.getProviderByName(name, userId);
10538            // If that didn't work, check if it exists for user 0 and then
10539            // verify that it's a singleton provider before using it.
10540            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10541                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10542                if (cpr != null) {
10543                    cpi = cpr.info;
10544                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10545                            cpi.name, cpi.flags)
10546                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10547                        userId = UserHandle.USER_SYSTEM;
10548                        checkCrossUser = false;
10549                    } else {
10550                        cpr = null;
10551                        cpi = null;
10552                    }
10553                }
10554            }
10555
10556            boolean providerRunning = cpr != null;
10557            if (providerRunning) {
10558                cpi = cpr.info;
10559                String msg;
10560                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10561                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10562                        != null) {
10563                    throw new SecurityException(msg);
10564                }
10565                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10566
10567                if (r != null && cpr.canRunHere(r)) {
10568                    // This provider has been published or is in the process
10569                    // of being published...  but it is also allowed to run
10570                    // in the caller's process, so don't make a connection
10571                    // and just let the caller instantiate its own instance.
10572                    ContentProviderHolder holder = cpr.newHolder(null);
10573                    // don't give caller the provider object, it needs
10574                    // to make its own.
10575                    holder.provider = null;
10576                    return holder;
10577                }
10578
10579                final long origId = Binder.clearCallingIdentity();
10580
10581                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10582
10583                // In this case the provider instance already exists, so we can
10584                // return it right away.
10585                conn = incProviderCountLocked(r, cpr, token, stable);
10586                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10587                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10588                        // If this is a perceptible app accessing the provider,
10589                        // make sure to count it as being accessed and thus
10590                        // back up on the LRU list.  This is good because
10591                        // content providers are often expensive to start.
10592                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10593                        updateLruProcessLocked(cpr.proc, false, null);
10594                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10595                    }
10596                }
10597
10598                if (cpr.proc != null) {
10599                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10600                    boolean success = updateOomAdjLocked(cpr.proc);
10601                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10602                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10603                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10604                    // NOTE: there is still a race here where a signal could be
10605                    // pending on the process even though we managed to update its
10606                    // adj level.  Not sure what to do about this, but at least
10607                    // the race is now smaller.
10608                    if (!success) {
10609                        // Uh oh...  it looks like the provider's process
10610                        // has been killed on us.  We need to wait for a new
10611                        // process to be started, and make sure its death
10612                        // doesn't kill our process.
10613                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10614                                + " is crashing; detaching " + r);
10615                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10616                        checkTime(startTime, "getContentProviderImpl: before appDied");
10617                        appDiedLocked(cpr.proc);
10618                        checkTime(startTime, "getContentProviderImpl: after appDied");
10619                        if (!lastRef) {
10620                            // This wasn't the last ref our process had on
10621                            // the provider...  we have now been killed, bail.
10622                            return null;
10623                        }
10624                        providerRunning = false;
10625                        conn = null;
10626                    }
10627                }
10628
10629                Binder.restoreCallingIdentity(origId);
10630            }
10631
10632            if (!providerRunning) {
10633                try {
10634                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10635                    cpi = AppGlobals.getPackageManager().
10636                        resolveContentProvider(name,
10637                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10638                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10639                } catch (RemoteException ex) {
10640                }
10641                if (cpi == null) {
10642                    return null;
10643                }
10644                // If the provider is a singleton AND
10645                // (it's a call within the same user || the provider is a
10646                // privileged app)
10647                // Then allow connecting to the singleton provider
10648                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10649                        cpi.name, cpi.flags)
10650                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10651                if (singleton) {
10652                    userId = UserHandle.USER_SYSTEM;
10653                }
10654                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10655                checkTime(startTime, "getContentProviderImpl: got app info for user");
10656
10657                String msg;
10658                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10659                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10660                        != null) {
10661                    throw new SecurityException(msg);
10662                }
10663                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10664
10665                if (!mProcessesReady
10666                        && !cpi.processName.equals("system")) {
10667                    // If this content provider does not run in the system
10668                    // process, and the system is not yet ready to run other
10669                    // processes, then fail fast instead of hanging.
10670                    throw new IllegalArgumentException(
10671                            "Attempt to launch content provider before system ready");
10672                }
10673
10674                // Make sure that the user who owns this provider is running.  If not,
10675                // we don't want to allow it to run.
10676                if (!mUserController.isUserRunningLocked(userId, 0)) {
10677                    Slog.w(TAG, "Unable to launch app "
10678                            + cpi.applicationInfo.packageName + "/"
10679                            + cpi.applicationInfo.uid + " for provider "
10680                            + name + ": user " + userId + " is stopped");
10681                    return null;
10682                }
10683
10684                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10685                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10686                cpr = mProviderMap.getProviderByClass(comp, userId);
10687                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10688                final boolean firstClass = cpr == null;
10689                if (firstClass) {
10690                    final long ident = Binder.clearCallingIdentity();
10691
10692                    // If permissions need a review before any of the app components can run,
10693                    // we return no provider and launch a review activity if the calling app
10694                    // is in the foreground.
10695                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10696                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10697                            return null;
10698                        }
10699                    }
10700
10701                    try {
10702                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10703                        ApplicationInfo ai =
10704                            AppGlobals.getPackageManager().
10705                                getApplicationInfo(
10706                                        cpi.applicationInfo.packageName,
10707                                        STOCK_PM_FLAGS, userId);
10708                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10709                        if (ai == null) {
10710                            Slog.w(TAG, "No package info for content provider "
10711                                    + cpi.name);
10712                            return null;
10713                        }
10714                        ai = getAppInfoForUser(ai, userId);
10715                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10716                    } catch (RemoteException ex) {
10717                        // pm is in same process, this will never happen.
10718                    } finally {
10719                        Binder.restoreCallingIdentity(ident);
10720                    }
10721                }
10722
10723                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10724
10725                if (r != null && cpr.canRunHere(r)) {
10726                    // If this is a multiprocess provider, then just return its
10727                    // info and allow the caller to instantiate it.  Only do
10728                    // this if the provider is the same user as the caller's
10729                    // process, or can run as root (so can be in any process).
10730                    return cpr.newHolder(null);
10731                }
10732
10733                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10734                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10735                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10736
10737                // This is single process, and our app is now connecting to it.
10738                // See if we are already in the process of launching this
10739                // provider.
10740                final int N = mLaunchingProviders.size();
10741                int i;
10742                for (i = 0; i < N; i++) {
10743                    if (mLaunchingProviders.get(i) == cpr) {
10744                        break;
10745                    }
10746                }
10747
10748                // If the provider is not already being launched, then get it
10749                // started.
10750                if (i >= N) {
10751                    final long origId = Binder.clearCallingIdentity();
10752
10753                    try {
10754                        // Content provider is now in use, its package can't be stopped.
10755                        try {
10756                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10757                            AppGlobals.getPackageManager().setPackageStoppedState(
10758                                    cpr.appInfo.packageName, false, userId);
10759                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10760                        } catch (RemoteException e) {
10761                        } catch (IllegalArgumentException e) {
10762                            Slog.w(TAG, "Failed trying to unstop package "
10763                                    + cpr.appInfo.packageName + ": " + e);
10764                        }
10765
10766                        // Use existing process if already started
10767                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10768                        ProcessRecord proc = getProcessRecordLocked(
10769                                cpi.processName, cpr.appInfo.uid, false);
10770                        if (proc != null && proc.thread != null) {
10771                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10772                                    "Installing in existing process " + proc);
10773                            if (!proc.pubProviders.containsKey(cpi.name)) {
10774                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10775                                proc.pubProviders.put(cpi.name, cpr);
10776                                try {
10777                                    proc.thread.scheduleInstallProvider(cpi);
10778                                } catch (RemoteException e) {
10779                                }
10780                            }
10781                        } else {
10782                            checkTime(startTime, "getContentProviderImpl: before start process");
10783                            proc = startProcessLocked(cpi.processName,
10784                                    cpr.appInfo, false, 0, "content provider",
10785                                    new ComponentName(cpi.applicationInfo.packageName,
10786                                            cpi.name), false, false, false);
10787                            checkTime(startTime, "getContentProviderImpl: after start process");
10788                            if (proc == null) {
10789                                Slog.w(TAG, "Unable to launch app "
10790                                        + cpi.applicationInfo.packageName + "/"
10791                                        + cpi.applicationInfo.uid + " for provider "
10792                                        + name + ": process is bad");
10793                                return null;
10794                            }
10795                        }
10796                        cpr.launchingApp = proc;
10797                        mLaunchingProviders.add(cpr);
10798                    } finally {
10799                        Binder.restoreCallingIdentity(origId);
10800                    }
10801                }
10802
10803                checkTime(startTime, "getContentProviderImpl: updating data structures");
10804
10805                // Make sure the provider is published (the same provider class
10806                // may be published under multiple names).
10807                if (firstClass) {
10808                    mProviderMap.putProviderByClass(comp, cpr);
10809                }
10810
10811                mProviderMap.putProviderByName(name, cpr);
10812                conn = incProviderCountLocked(r, cpr, token, stable);
10813                if (conn != null) {
10814                    conn.waiting = true;
10815                }
10816            }
10817            checkTime(startTime, "getContentProviderImpl: done!");
10818        }
10819
10820        // Wait for the provider to be published...
10821        synchronized (cpr) {
10822            while (cpr.provider == null) {
10823                if (cpr.launchingApp == null) {
10824                    Slog.w(TAG, "Unable to launch app "
10825                            + cpi.applicationInfo.packageName + "/"
10826                            + cpi.applicationInfo.uid + " for provider "
10827                            + name + ": launching app became null");
10828                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10829                            UserHandle.getUserId(cpi.applicationInfo.uid),
10830                            cpi.applicationInfo.packageName,
10831                            cpi.applicationInfo.uid, name);
10832                    return null;
10833                }
10834                try {
10835                    if (DEBUG_MU) Slog.v(TAG_MU,
10836                            "Waiting to start provider " + cpr
10837                            + " launchingApp=" + cpr.launchingApp);
10838                    if (conn != null) {
10839                        conn.waiting = true;
10840                    }
10841                    cpr.wait();
10842                } catch (InterruptedException ex) {
10843                } finally {
10844                    if (conn != null) {
10845                        conn.waiting = false;
10846                    }
10847                }
10848            }
10849        }
10850        return cpr != null ? cpr.newHolder(conn) : null;
10851    }
10852
10853    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10854            ProcessRecord r, final int userId) {
10855        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10856                cpi.packageName, userId)) {
10857
10858            final boolean callerForeground = r == null || r.setSchedGroup
10859                    != ProcessList.SCHED_GROUP_BACKGROUND;
10860
10861            // Show a permission review UI only for starting from a foreground app
10862            if (!callerForeground) {
10863                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10864                        + cpi.packageName + " requires a permissions review");
10865                return false;
10866            }
10867
10868            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10869            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10870                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10871            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10872
10873            if (DEBUG_PERMISSIONS_REVIEW) {
10874                Slog.i(TAG, "u" + userId + " Launching permission review "
10875                        + "for package " + cpi.packageName);
10876            }
10877
10878            final UserHandle userHandle = new UserHandle(userId);
10879            mHandler.post(new Runnable() {
10880                @Override
10881                public void run() {
10882                    mContext.startActivityAsUser(intent, userHandle);
10883                }
10884            });
10885
10886            return false;
10887        }
10888
10889        return true;
10890    }
10891
10892    PackageManagerInternal getPackageManagerInternalLocked() {
10893        if (mPackageManagerInt == null) {
10894            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10895        }
10896        return mPackageManagerInt;
10897    }
10898
10899    @Override
10900    public final ContentProviderHolder getContentProvider(
10901            IApplicationThread caller, String name, int userId, boolean stable) {
10902        enforceNotIsolatedCaller("getContentProvider");
10903        if (caller == null) {
10904            String msg = "null IApplicationThread when getting content provider "
10905                    + name;
10906            Slog.w(TAG, msg);
10907            throw new SecurityException(msg);
10908        }
10909        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10910        // with cross-user grant.
10911        return getContentProviderImpl(caller, name, null, stable, userId);
10912    }
10913
10914    public ContentProviderHolder getContentProviderExternal(
10915            String name, int userId, IBinder token) {
10916        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10917            "Do not have permission in call getContentProviderExternal()");
10918        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10919                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10920        return getContentProviderExternalUnchecked(name, token, userId);
10921    }
10922
10923    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10924            IBinder token, int userId) {
10925        return getContentProviderImpl(null, name, token, true, userId);
10926    }
10927
10928    /**
10929     * Drop a content provider from a ProcessRecord's bookkeeping
10930     */
10931    public void removeContentProvider(IBinder connection, boolean stable) {
10932        enforceNotIsolatedCaller("removeContentProvider");
10933        long ident = Binder.clearCallingIdentity();
10934        try {
10935            synchronized (this) {
10936                ContentProviderConnection conn;
10937                try {
10938                    conn = (ContentProviderConnection)connection;
10939                } catch (ClassCastException e) {
10940                    String msg ="removeContentProvider: " + connection
10941                            + " not a ContentProviderConnection";
10942                    Slog.w(TAG, msg);
10943                    throw new IllegalArgumentException(msg);
10944                }
10945                if (conn == null) {
10946                    throw new NullPointerException("connection is null");
10947                }
10948                if (decProviderCountLocked(conn, null, null, stable)) {
10949                    updateOomAdjLocked();
10950                }
10951            }
10952        } finally {
10953            Binder.restoreCallingIdentity(ident);
10954        }
10955    }
10956
10957    public void removeContentProviderExternal(String name, IBinder token) {
10958        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10959            "Do not have permission in call removeContentProviderExternal()");
10960        int userId = UserHandle.getCallingUserId();
10961        long ident = Binder.clearCallingIdentity();
10962        try {
10963            removeContentProviderExternalUnchecked(name, token, userId);
10964        } finally {
10965            Binder.restoreCallingIdentity(ident);
10966        }
10967    }
10968
10969    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10970        synchronized (this) {
10971            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10972            if(cpr == null) {
10973                //remove from mProvidersByClass
10974                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10975                return;
10976            }
10977
10978            //update content provider record entry info
10979            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10980            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10981            if (localCpr.hasExternalProcessHandles()) {
10982                if (localCpr.removeExternalProcessHandleLocked(token)) {
10983                    updateOomAdjLocked();
10984                } else {
10985                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10986                            + " with no external reference for token: "
10987                            + token + ".");
10988                }
10989            } else {
10990                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10991                        + " with no external references.");
10992            }
10993        }
10994    }
10995
10996    public final void publishContentProviders(IApplicationThread caller,
10997            List<ContentProviderHolder> providers) {
10998        if (providers == null) {
10999            return;
11000        }
11001
11002        enforceNotIsolatedCaller("publishContentProviders");
11003        synchronized (this) {
11004            final ProcessRecord r = getRecordForAppLocked(caller);
11005            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11006            if (r == null) {
11007                throw new SecurityException(
11008                        "Unable to find app for caller " + caller
11009                      + " (pid=" + Binder.getCallingPid()
11010                      + ") when publishing content providers");
11011            }
11012
11013            final long origId = Binder.clearCallingIdentity();
11014
11015            final int N = providers.size();
11016            for (int i = 0; i < N; i++) {
11017                ContentProviderHolder src = providers.get(i);
11018                if (src == null || src.info == null || src.provider == null) {
11019                    continue;
11020                }
11021                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11022                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11023                if (dst != null) {
11024                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11025                    mProviderMap.putProviderByClass(comp, dst);
11026                    String names[] = dst.info.authority.split(";");
11027                    for (int j = 0; j < names.length; j++) {
11028                        mProviderMap.putProviderByName(names[j], dst);
11029                    }
11030
11031                    int launchingCount = mLaunchingProviders.size();
11032                    int j;
11033                    boolean wasInLaunchingProviders = false;
11034                    for (j = 0; j < launchingCount; j++) {
11035                        if (mLaunchingProviders.get(j) == dst) {
11036                            mLaunchingProviders.remove(j);
11037                            wasInLaunchingProviders = true;
11038                            j--;
11039                            launchingCount--;
11040                        }
11041                    }
11042                    if (wasInLaunchingProviders) {
11043                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11044                    }
11045                    synchronized (dst) {
11046                        dst.provider = src.provider;
11047                        dst.proc = r;
11048                        dst.notifyAll();
11049                    }
11050                    updateOomAdjLocked(r);
11051                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11052                            src.info.authority);
11053                }
11054            }
11055
11056            Binder.restoreCallingIdentity(origId);
11057        }
11058    }
11059
11060    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11061        ContentProviderConnection conn;
11062        try {
11063            conn = (ContentProviderConnection)connection;
11064        } catch (ClassCastException e) {
11065            String msg ="refContentProvider: " + connection
11066                    + " not a ContentProviderConnection";
11067            Slog.w(TAG, msg);
11068            throw new IllegalArgumentException(msg);
11069        }
11070        if (conn == null) {
11071            throw new NullPointerException("connection is null");
11072        }
11073
11074        synchronized (this) {
11075            if (stable > 0) {
11076                conn.numStableIncs += stable;
11077            }
11078            stable = conn.stableCount + stable;
11079            if (stable < 0) {
11080                throw new IllegalStateException("stableCount < 0: " + stable);
11081            }
11082
11083            if (unstable > 0) {
11084                conn.numUnstableIncs += unstable;
11085            }
11086            unstable = conn.unstableCount + unstable;
11087            if (unstable < 0) {
11088                throw new IllegalStateException("unstableCount < 0: " + unstable);
11089            }
11090
11091            if ((stable+unstable) <= 0) {
11092                throw new IllegalStateException("ref counts can't go to zero here: stable="
11093                        + stable + " unstable=" + unstable);
11094            }
11095            conn.stableCount = stable;
11096            conn.unstableCount = unstable;
11097            return !conn.dead;
11098        }
11099    }
11100
11101    public void unstableProviderDied(IBinder connection) {
11102        ContentProviderConnection conn;
11103        try {
11104            conn = (ContentProviderConnection)connection;
11105        } catch (ClassCastException e) {
11106            String msg ="refContentProvider: " + connection
11107                    + " not a ContentProviderConnection";
11108            Slog.w(TAG, msg);
11109            throw new IllegalArgumentException(msg);
11110        }
11111        if (conn == null) {
11112            throw new NullPointerException("connection is null");
11113        }
11114
11115        // Safely retrieve the content provider associated with the connection.
11116        IContentProvider provider;
11117        synchronized (this) {
11118            provider = conn.provider.provider;
11119        }
11120
11121        if (provider == null) {
11122            // Um, yeah, we're way ahead of you.
11123            return;
11124        }
11125
11126        // Make sure the caller is being honest with us.
11127        if (provider.asBinder().pingBinder()) {
11128            // Er, no, still looks good to us.
11129            synchronized (this) {
11130                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11131                        + " says " + conn + " died, but we don't agree");
11132                return;
11133            }
11134        }
11135
11136        // Well look at that!  It's dead!
11137        synchronized (this) {
11138            if (conn.provider.provider != provider) {
11139                // But something changed...  good enough.
11140                return;
11141            }
11142
11143            ProcessRecord proc = conn.provider.proc;
11144            if (proc == null || proc.thread == null) {
11145                // Seems like the process is already cleaned up.
11146                return;
11147            }
11148
11149            // As far as we're concerned, this is just like receiving a
11150            // death notification...  just a bit prematurely.
11151            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11152                    + ") early provider death");
11153            final long ident = Binder.clearCallingIdentity();
11154            try {
11155                appDiedLocked(proc);
11156            } finally {
11157                Binder.restoreCallingIdentity(ident);
11158            }
11159        }
11160    }
11161
11162    @Override
11163    public void appNotRespondingViaProvider(IBinder connection) {
11164        enforceCallingPermission(
11165                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11166
11167        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11168        if (conn == null) {
11169            Slog.w(TAG, "ContentProviderConnection is null");
11170            return;
11171        }
11172
11173        final ProcessRecord host = conn.provider.proc;
11174        if (host == null) {
11175            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11176            return;
11177        }
11178
11179        mHandler.post(new Runnable() {
11180            @Override
11181            public void run() {
11182                mAppErrors.appNotResponding(host, null, null, false,
11183                        "ContentProvider not responding");
11184            }
11185        });
11186    }
11187
11188    public final void installSystemProviders() {
11189        List<ProviderInfo> providers;
11190        synchronized (this) {
11191            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11192            providers = generateApplicationProvidersLocked(app);
11193            if (providers != null) {
11194                for (int i=providers.size()-1; i>=0; i--) {
11195                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11196                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11197                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11198                                + ": not system .apk");
11199                        providers.remove(i);
11200                    }
11201                }
11202            }
11203        }
11204        if (providers != null) {
11205            mSystemThread.installSystemProviders(providers);
11206        }
11207
11208        mCoreSettingsObserver = new CoreSettingsObserver(this);
11209        mFontScaleSettingObserver = new FontScaleSettingObserver();
11210
11211        //mUsageStatsService.monitorPackages();
11212    }
11213
11214    private void startPersistentApps(int matchFlags) {
11215        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11216
11217        synchronized (this) {
11218            try {
11219                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11220                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11221                for (ApplicationInfo app : apps) {
11222                    if (!"android".equals(app.packageName)) {
11223                        addAppLocked(app, false, null /* ABI override */);
11224                    }
11225                }
11226            } catch (RemoteException ex) {
11227            }
11228        }
11229    }
11230
11231    /**
11232     * When a user is unlocked, we need to install encryption-unaware providers
11233     * belonging to any running apps.
11234     */
11235    private void installEncryptionUnawareProviders(int userId) {
11236        // We're only interested in providers that are encryption unaware, and
11237        // we don't care about uninstalled apps, since there's no way they're
11238        // running at this point.
11239        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11240
11241        synchronized (this) {
11242            final int NP = mProcessNames.getMap().size();
11243            for (int ip = 0; ip < NP; ip++) {
11244                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11245                final int NA = apps.size();
11246                for (int ia = 0; ia < NA; ia++) {
11247                    final ProcessRecord app = apps.valueAt(ia);
11248                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11249
11250                    final int NG = app.pkgList.size();
11251                    for (int ig = 0; ig < NG; ig++) {
11252                        try {
11253                            final String pkgName = app.pkgList.keyAt(ig);
11254                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11255                                    .getPackageInfo(pkgName, matchFlags, userId);
11256                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11257                                for (ProviderInfo pi : pkgInfo.providers) {
11258                                    // TODO: keep in sync with generateApplicationProvidersLocked
11259                                    final boolean processMatch = Objects.equals(pi.processName,
11260                                            app.processName) || pi.multiprocess;
11261                                    final boolean userMatch = isSingleton(pi.processName,
11262                                            pi.applicationInfo, pi.name, pi.flags)
11263                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11264                                    if (processMatch && userMatch) {
11265                                        Log.v(TAG, "Installing " + pi);
11266                                        app.thread.scheduleInstallProvider(pi);
11267                                    } else {
11268                                        Log.v(TAG, "Skipping " + pi);
11269                                    }
11270                                }
11271                            }
11272                        } catch (RemoteException ignored) {
11273                        }
11274                    }
11275                }
11276            }
11277        }
11278    }
11279
11280    /**
11281     * Allows apps to retrieve the MIME type of a URI.
11282     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11283     * users, then it does not need permission to access the ContentProvider.
11284     * Either, it needs cross-user uri grants.
11285     *
11286     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11287     *
11288     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11289     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11290     */
11291    public String getProviderMimeType(Uri uri, int userId) {
11292        enforceNotIsolatedCaller("getProviderMimeType");
11293        final String name = uri.getAuthority();
11294        int callingUid = Binder.getCallingUid();
11295        int callingPid = Binder.getCallingPid();
11296        long ident = 0;
11297        boolean clearedIdentity = false;
11298        synchronized (this) {
11299            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11300        }
11301        if (canClearIdentity(callingPid, callingUid, userId)) {
11302            clearedIdentity = true;
11303            ident = Binder.clearCallingIdentity();
11304        }
11305        ContentProviderHolder holder = null;
11306        try {
11307            holder = getContentProviderExternalUnchecked(name, null, userId);
11308            if (holder != null) {
11309                return holder.provider.getType(uri);
11310            }
11311        } catch (RemoteException e) {
11312            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11313            return null;
11314        } catch (Exception e) {
11315            Log.w(TAG, "Exception while determining type of " + uri, e);
11316            return null;
11317        } finally {
11318            // We need to clear the identity to call removeContentProviderExternalUnchecked
11319            if (!clearedIdentity) {
11320                ident = Binder.clearCallingIdentity();
11321            }
11322            try {
11323                if (holder != null) {
11324                    removeContentProviderExternalUnchecked(name, null, userId);
11325                }
11326            } finally {
11327                Binder.restoreCallingIdentity(ident);
11328            }
11329        }
11330
11331        return null;
11332    }
11333
11334    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11335        if (UserHandle.getUserId(callingUid) == userId) {
11336            return true;
11337        }
11338        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11339                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11340                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11341                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11342                return true;
11343        }
11344        return false;
11345    }
11346
11347    // =========================================================
11348    // GLOBAL MANAGEMENT
11349    // =========================================================
11350
11351    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11352            boolean isolated, int isolatedUid) {
11353        String proc = customProcess != null ? customProcess : info.processName;
11354        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11355        final int userId = UserHandle.getUserId(info.uid);
11356        int uid = info.uid;
11357        if (isolated) {
11358            if (isolatedUid == 0) {
11359                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11360                while (true) {
11361                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11362                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11363                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11364                    }
11365                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11366                    mNextIsolatedProcessUid++;
11367                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11368                        // No process for this uid, use it.
11369                        break;
11370                    }
11371                    stepsLeft--;
11372                    if (stepsLeft <= 0) {
11373                        return null;
11374                    }
11375                }
11376            } else {
11377                // Special case for startIsolatedProcess (internal only), where
11378                // the uid of the isolated process is specified by the caller.
11379                uid = isolatedUid;
11380            }
11381        }
11382        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11383        if (!mBooted && !mBooting
11384                && userId == UserHandle.USER_SYSTEM
11385                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11386            r.persistent = true;
11387        }
11388        addProcessNameLocked(r);
11389        return r;
11390    }
11391
11392    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11393            String abiOverride) {
11394        ProcessRecord app;
11395        if (!isolated) {
11396            app = getProcessRecordLocked(info.processName, info.uid, true);
11397        } else {
11398            app = null;
11399        }
11400
11401        if (app == null) {
11402            app = newProcessRecordLocked(info, null, isolated, 0);
11403            updateLruProcessLocked(app, false, null);
11404            updateOomAdjLocked();
11405        }
11406
11407        // This package really, really can not be stopped.
11408        try {
11409            AppGlobals.getPackageManager().setPackageStoppedState(
11410                    info.packageName, false, UserHandle.getUserId(app.uid));
11411        } catch (RemoteException e) {
11412        } catch (IllegalArgumentException e) {
11413            Slog.w(TAG, "Failed trying to unstop package "
11414                    + info.packageName + ": " + e);
11415        }
11416
11417        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11418            app.persistent = true;
11419            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11420        }
11421        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11422            mPersistentStartingProcesses.add(app);
11423            startProcessLocked(app, "added application", app.processName, abiOverride,
11424                    null /* entryPoint */, null /* entryPointArgs */);
11425        }
11426
11427        return app;
11428    }
11429
11430    public void unhandledBack() {
11431        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11432                "unhandledBack()");
11433
11434        synchronized(this) {
11435            final long origId = Binder.clearCallingIdentity();
11436            try {
11437                getFocusedStack().unhandledBackLocked();
11438            } finally {
11439                Binder.restoreCallingIdentity(origId);
11440            }
11441        }
11442    }
11443
11444    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11445        enforceNotIsolatedCaller("openContentUri");
11446        final int userId = UserHandle.getCallingUserId();
11447        String name = uri.getAuthority();
11448        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11449        ParcelFileDescriptor pfd = null;
11450        if (cph != null) {
11451            // We record the binder invoker's uid in thread-local storage before
11452            // going to the content provider to open the file.  Later, in the code
11453            // that handles all permissions checks, we look for this uid and use
11454            // that rather than the Activity Manager's own uid.  The effect is that
11455            // we do the check against the caller's permissions even though it looks
11456            // to the content provider like the Activity Manager itself is making
11457            // the request.
11458            Binder token = new Binder();
11459            sCallerIdentity.set(new Identity(
11460                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11461            try {
11462                pfd = cph.provider.openFile(null, uri, "r", null, token);
11463            } catch (FileNotFoundException e) {
11464                // do nothing; pfd will be returned null
11465            } finally {
11466                // Ensure that whatever happens, we clean up the identity state
11467                sCallerIdentity.remove();
11468                // Ensure we're done with the provider.
11469                removeContentProviderExternalUnchecked(name, null, userId);
11470            }
11471        } else {
11472            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11473        }
11474        return pfd;
11475    }
11476
11477    // Actually is sleeping or shutting down or whatever else in the future
11478    // is an inactive state.
11479    boolean isSleepingOrShuttingDownLocked() {
11480        return isSleepingLocked() || mShuttingDown;
11481    }
11482
11483    boolean isShuttingDownLocked() {
11484        return mShuttingDown;
11485    }
11486
11487    boolean isSleepingLocked() {
11488        return mSleeping;
11489    }
11490
11491    void onWakefulnessChanged(int wakefulness) {
11492        synchronized(this) {
11493            mWakefulness = wakefulness;
11494            updateSleepIfNeededLocked();
11495        }
11496    }
11497
11498    void finishRunningVoiceLocked() {
11499        if (mRunningVoice != null) {
11500            mRunningVoice = null;
11501            mVoiceWakeLock.release();
11502            updateSleepIfNeededLocked();
11503        }
11504    }
11505
11506    void startTimeTrackingFocusedActivityLocked() {
11507        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11508            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11509        }
11510    }
11511
11512    void updateSleepIfNeededLocked() {
11513        if (mSleeping && !shouldSleepLocked()) {
11514            mSleeping = false;
11515            startTimeTrackingFocusedActivityLocked();
11516            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11517            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11518            updateOomAdjLocked();
11519        } else if (!mSleeping && shouldSleepLocked()) {
11520            mSleeping = true;
11521            if (mCurAppTimeTracker != null) {
11522                mCurAppTimeTracker.stop();
11523            }
11524            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11525            mStackSupervisor.goingToSleepLocked();
11526            updateOomAdjLocked();
11527
11528            // Initialize the wake times of all processes.
11529            checkExcessivePowerUsageLocked(false);
11530            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11531            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11532            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11533        }
11534    }
11535
11536    private boolean shouldSleepLocked() {
11537        // Resume applications while running a voice interactor.
11538        if (mRunningVoice != null) {
11539            return false;
11540        }
11541
11542        // TODO: Transform the lock screen state into a sleep token instead.
11543        switch (mWakefulness) {
11544            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11545            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11546            case PowerManagerInternal.WAKEFULNESS_DOZING:
11547                // Pause applications whenever the lock screen is shown or any sleep
11548                // tokens have been acquired.
11549                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11550            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11551            default:
11552                // If we're asleep then pause applications unconditionally.
11553                return true;
11554        }
11555    }
11556
11557    /** Pokes the task persister. */
11558    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11559        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11560    }
11561
11562    /** Notifies all listeners when the task stack has changed. */
11563    void notifyTaskStackChangedLocked() {
11564        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11565        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11566        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11567        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11568    }
11569
11570    /** Notifies all listeners when an Activity is pinned. */
11571    void notifyActivityPinnedLocked() {
11572        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11573        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11574    }
11575
11576    /**
11577     * Notifies all listeners when an attempt was made to start an an activity that is already
11578     * running in the pinned stack and the activity was not actually started, but the task is
11579     * either brought to the front or a new Intent is delivered to it.
11580     */
11581    void notifyPinnedActivityRestartAttemptLocked() {
11582        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11583        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11584    }
11585
11586    /** Notifies all listeners when the pinned stack animation ends. */
11587    @Override
11588    public void notifyPinnedStackAnimationEnded() {
11589        synchronized (this) {
11590            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11591            mHandler.obtainMessage(
11592                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11593        }
11594    }
11595
11596    @Override
11597    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11598        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11599    }
11600
11601    @Override
11602    public boolean shutdown(int timeout) {
11603        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11604                != PackageManager.PERMISSION_GRANTED) {
11605            throw new SecurityException("Requires permission "
11606                    + android.Manifest.permission.SHUTDOWN);
11607        }
11608
11609        boolean timedout = false;
11610
11611        synchronized(this) {
11612            mShuttingDown = true;
11613            updateEventDispatchingLocked();
11614            timedout = mStackSupervisor.shutdownLocked(timeout);
11615        }
11616
11617        mAppOpsService.shutdown();
11618        if (mUsageStatsService != null) {
11619            mUsageStatsService.prepareShutdown();
11620        }
11621        mBatteryStatsService.shutdown();
11622        synchronized (this) {
11623            mProcessStats.shutdownLocked();
11624            notifyTaskPersisterLocked(null, true);
11625        }
11626
11627        return timedout;
11628    }
11629
11630    public final void activitySlept(IBinder token) {
11631        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11632
11633        final long origId = Binder.clearCallingIdentity();
11634
11635        synchronized (this) {
11636            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11637            if (r != null) {
11638                mStackSupervisor.activitySleptLocked(r);
11639            }
11640        }
11641
11642        Binder.restoreCallingIdentity(origId);
11643    }
11644
11645    private String lockScreenShownToString() {
11646        switch (mLockScreenShown) {
11647            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11648            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11649            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11650            default: return "Unknown=" + mLockScreenShown;
11651        }
11652    }
11653
11654    void logLockScreen(String msg) {
11655        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11656                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11657                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11658                + " mSleeping=" + mSleeping);
11659    }
11660
11661    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11662        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11663        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11664        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11665            boolean wasRunningVoice = mRunningVoice != null;
11666            mRunningVoice = session;
11667            if (!wasRunningVoice) {
11668                mVoiceWakeLock.acquire();
11669                updateSleepIfNeededLocked();
11670            }
11671        }
11672    }
11673
11674    private void updateEventDispatchingLocked() {
11675        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11676    }
11677
11678    public void setLockScreenShown(boolean showing, boolean occluded) {
11679        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11680                != PackageManager.PERMISSION_GRANTED) {
11681            throw new SecurityException("Requires permission "
11682                    + android.Manifest.permission.DEVICE_POWER);
11683        }
11684
11685        synchronized(this) {
11686            long ident = Binder.clearCallingIdentity();
11687            try {
11688                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11689                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11690                if (showing && occluded) {
11691                    // The lock screen is currently showing, but is occluded by a window that can
11692                    // show on top of the lock screen. In this can we want to dismiss the docked
11693                    // stack since it will be complicated/risky to try to put the activity on top
11694                    // of the lock screen in the right fullscreen configuration.
11695                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11696                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11697                }
11698
11699                updateSleepIfNeededLocked();
11700            } finally {
11701                Binder.restoreCallingIdentity(ident);
11702            }
11703        }
11704    }
11705
11706    @Override
11707    public void notifyLockedProfile(@UserIdInt int userId) {
11708        try {
11709            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11710                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11711            }
11712        } catch (RemoteException ex) {
11713            throw new SecurityException("Fail to check is caller a privileged app", ex);
11714        }
11715
11716        synchronized (this) {
11717            if (mStackSupervisor.isUserLockedProfile(userId)) {
11718                final long ident = Binder.clearCallingIdentity();
11719                try {
11720                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11721                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11722                        // If there is no device lock, we will show the profile's credential page.
11723                        mActivityStarter.showConfirmDeviceCredential(userId);
11724                    } else {
11725                        // Showing launcher to avoid user entering credential twice.
11726                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11727                    }
11728                } finally {
11729                    Binder.restoreCallingIdentity(ident);
11730                }
11731            }
11732        }
11733    }
11734
11735    @Override
11736    public void startConfirmDeviceCredentialIntent(Intent intent) {
11737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11738        synchronized (this) {
11739            final long ident = Binder.clearCallingIdentity();
11740            try {
11741                mActivityStarter.startConfirmCredentialIntent(intent);
11742            } finally {
11743                Binder.restoreCallingIdentity(ident);
11744            }
11745        }
11746    }
11747
11748    @Override
11749    public void stopAppSwitches() {
11750        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11751                != PackageManager.PERMISSION_GRANTED) {
11752            throw new SecurityException("viewquires permission "
11753                    + android.Manifest.permission.STOP_APP_SWITCHES);
11754        }
11755
11756        synchronized(this) {
11757            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11758                    + APP_SWITCH_DELAY_TIME;
11759            mDidAppSwitch = false;
11760            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11761            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11762            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11763        }
11764    }
11765
11766    public void resumeAppSwitches() {
11767        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11768                != PackageManager.PERMISSION_GRANTED) {
11769            throw new SecurityException("Requires permission "
11770                    + android.Manifest.permission.STOP_APP_SWITCHES);
11771        }
11772
11773        synchronized(this) {
11774            // Note that we don't execute any pending app switches... we will
11775            // let those wait until either the timeout, or the next start
11776            // activity request.
11777            mAppSwitchesAllowedTime = 0;
11778        }
11779    }
11780
11781    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11782            int callingPid, int callingUid, String name) {
11783        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11784            return true;
11785        }
11786
11787        int perm = checkComponentPermission(
11788                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11789                sourceUid, -1, true);
11790        if (perm == PackageManager.PERMISSION_GRANTED) {
11791            return true;
11792        }
11793
11794        // If the actual IPC caller is different from the logical source, then
11795        // also see if they are allowed to control app switches.
11796        if (callingUid != -1 && callingUid != sourceUid) {
11797            perm = checkComponentPermission(
11798                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11799                    callingUid, -1, true);
11800            if (perm == PackageManager.PERMISSION_GRANTED) {
11801                return true;
11802            }
11803        }
11804
11805        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11806        return false;
11807    }
11808
11809    public void setDebugApp(String packageName, boolean waitForDebugger,
11810            boolean persistent) {
11811        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11812                "setDebugApp()");
11813
11814        long ident = Binder.clearCallingIdentity();
11815        try {
11816            // Note that this is not really thread safe if there are multiple
11817            // callers into it at the same time, but that's not a situation we
11818            // care about.
11819            if (persistent) {
11820                final ContentResolver resolver = mContext.getContentResolver();
11821                Settings.Global.putString(
11822                    resolver, Settings.Global.DEBUG_APP,
11823                    packageName);
11824                Settings.Global.putInt(
11825                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11826                    waitForDebugger ? 1 : 0);
11827            }
11828
11829            synchronized (this) {
11830                if (!persistent) {
11831                    mOrigDebugApp = mDebugApp;
11832                    mOrigWaitForDebugger = mWaitForDebugger;
11833                }
11834                mDebugApp = packageName;
11835                mWaitForDebugger = waitForDebugger;
11836                mDebugTransient = !persistent;
11837                if (packageName != null) {
11838                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11839                            false, UserHandle.USER_ALL, "set debug app");
11840                }
11841            }
11842        } finally {
11843            Binder.restoreCallingIdentity(ident);
11844        }
11845    }
11846
11847    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11848        synchronized (this) {
11849            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11850            if (!isDebuggable) {
11851                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11852                    throw new SecurityException("Process not debuggable: " + app.packageName);
11853                }
11854            }
11855
11856            mTrackAllocationApp = processName;
11857        }
11858    }
11859
11860    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11861        synchronized (this) {
11862            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11863            if (!isDebuggable) {
11864                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11865                    throw new SecurityException("Process not debuggable: " + app.packageName);
11866                }
11867            }
11868            mProfileApp = processName;
11869            mProfileFile = profilerInfo.profileFile;
11870            if (mProfileFd != null) {
11871                try {
11872                    mProfileFd.close();
11873                } catch (IOException e) {
11874                }
11875                mProfileFd = null;
11876            }
11877            mProfileFd = profilerInfo.profileFd;
11878            mSamplingInterval = profilerInfo.samplingInterval;
11879            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11880            mProfileType = 0;
11881        }
11882    }
11883
11884    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11885        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11886        if (!isDebuggable) {
11887            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11888                throw new SecurityException("Process not debuggable: " + app.packageName);
11889            }
11890        }
11891        mNativeDebuggingApp = processName;
11892    }
11893
11894    @Override
11895    public void setAlwaysFinish(boolean enabled) {
11896        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11897                "setAlwaysFinish()");
11898
11899        long ident = Binder.clearCallingIdentity();
11900        try {
11901            Settings.Global.putInt(
11902                    mContext.getContentResolver(),
11903                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11904
11905            synchronized (this) {
11906                mAlwaysFinishActivities = enabled;
11907            }
11908        } finally {
11909            Binder.restoreCallingIdentity(ident);
11910        }
11911    }
11912
11913    @Override
11914    public void setLenientBackgroundCheck(boolean enabled) {
11915        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11916                "setLenientBackgroundCheck()");
11917
11918        long ident = Binder.clearCallingIdentity();
11919        try {
11920            Settings.Global.putInt(
11921                    mContext.getContentResolver(),
11922                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11923
11924            synchronized (this) {
11925                mLenientBackgroundCheck = enabled;
11926            }
11927        } finally {
11928            Binder.restoreCallingIdentity(ident);
11929        }
11930    }
11931
11932    @Override
11933    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11934        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11935                "setActivityController()");
11936        synchronized (this) {
11937            mController = controller;
11938            mControllerIsAMonkey = imAMonkey;
11939            Watchdog.getInstance().setActivityController(controller);
11940        }
11941    }
11942
11943    @Override
11944    public void setUserIsMonkey(boolean userIsMonkey) {
11945        synchronized (this) {
11946            synchronized (mPidsSelfLocked) {
11947                final int callingPid = Binder.getCallingPid();
11948                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11949                if (precessRecord == null) {
11950                    throw new SecurityException("Unknown process: " + callingPid);
11951                }
11952                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11953                    throw new SecurityException("Only an instrumentation process "
11954                            + "with a UiAutomation can call setUserIsMonkey");
11955                }
11956            }
11957            mUserIsMonkey = userIsMonkey;
11958        }
11959    }
11960
11961    @Override
11962    public boolean isUserAMonkey() {
11963        synchronized (this) {
11964            // If there is a controller also implies the user is a monkey.
11965            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11966        }
11967    }
11968
11969    public void requestBugReport(int bugreportType) {
11970        String service = null;
11971        switch (bugreportType) {
11972            case ActivityManager.BUGREPORT_OPTION_FULL:
11973                service = "bugreport";
11974                break;
11975            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11976                service = "bugreportplus";
11977                break;
11978            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11979                service = "bugreportremote";
11980                break;
11981        }
11982        if (service == null) {
11983            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11984                    + bugreportType);
11985        }
11986        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11987        SystemProperties.set("ctl.start", service);
11988    }
11989
11990    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11991        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11992    }
11993
11994    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11995        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11996            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11997        }
11998        return KEY_DISPATCHING_TIMEOUT;
11999    }
12000
12001    @Override
12002    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12003        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12004                != PackageManager.PERMISSION_GRANTED) {
12005            throw new SecurityException("Requires permission "
12006                    + android.Manifest.permission.FILTER_EVENTS);
12007        }
12008        ProcessRecord proc;
12009        long timeout;
12010        synchronized (this) {
12011            synchronized (mPidsSelfLocked) {
12012                proc = mPidsSelfLocked.get(pid);
12013            }
12014            timeout = getInputDispatchingTimeoutLocked(proc);
12015        }
12016
12017        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12018            return -1;
12019        }
12020
12021        return timeout;
12022    }
12023
12024    /**
12025     * Handle input dispatching timeouts.
12026     * Returns whether input dispatching should be aborted or not.
12027     */
12028    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12029            final ActivityRecord activity, final ActivityRecord parent,
12030            final boolean aboveSystem, String reason) {
12031        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12032                != PackageManager.PERMISSION_GRANTED) {
12033            throw new SecurityException("Requires permission "
12034                    + android.Manifest.permission.FILTER_EVENTS);
12035        }
12036
12037        final String annotation;
12038        if (reason == null) {
12039            annotation = "Input dispatching timed out";
12040        } else {
12041            annotation = "Input dispatching timed out (" + reason + ")";
12042        }
12043
12044        if (proc != null) {
12045            synchronized (this) {
12046                if (proc.debugging) {
12047                    return false;
12048                }
12049
12050                if (mDidDexOpt) {
12051                    // Give more time since we were dexopting.
12052                    mDidDexOpt = false;
12053                    return false;
12054                }
12055
12056                if (proc.instrumentationClass != null) {
12057                    Bundle info = new Bundle();
12058                    info.putString("shortMsg", "keyDispatchingTimedOut");
12059                    info.putString("longMsg", annotation);
12060                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12061                    return true;
12062                }
12063            }
12064            mHandler.post(new Runnable() {
12065                @Override
12066                public void run() {
12067                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12068                }
12069            });
12070        }
12071
12072        return true;
12073    }
12074
12075    @Override
12076    public Bundle getAssistContextExtras(int requestType) {
12077        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12078                null, null, true /* focused */, true /* newSessionId */,
12079                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12080        if (pae == null) {
12081            return null;
12082        }
12083        synchronized (pae) {
12084            while (!pae.haveResult) {
12085                try {
12086                    pae.wait();
12087                } catch (InterruptedException e) {
12088                }
12089            }
12090        }
12091        synchronized (this) {
12092            buildAssistBundleLocked(pae, pae.result);
12093            mPendingAssistExtras.remove(pae);
12094            mUiHandler.removeCallbacks(pae);
12095        }
12096        return pae.extras;
12097    }
12098
12099    @Override
12100    public boolean isAssistDataAllowedOnCurrentActivity() {
12101        int userId;
12102        synchronized (this) {
12103            userId = mUserController.getCurrentUserIdLocked();
12104            ActivityRecord activity = getFocusedStack().topActivity();
12105            if (activity == null) {
12106                return false;
12107            }
12108            userId = activity.userId;
12109        }
12110        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12111                Context.DEVICE_POLICY_SERVICE);
12112        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12113    }
12114
12115    @Override
12116    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12117        long ident = Binder.clearCallingIdentity();
12118        try {
12119            synchronized (this) {
12120                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12121                ActivityRecord top = getFocusedStack().topActivity();
12122                if (top != caller) {
12123                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12124                            + " is not current top " + top);
12125                    return false;
12126                }
12127                if (!top.nowVisible) {
12128                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12129                            + " is not visible");
12130                    return false;
12131                }
12132            }
12133            AssistUtils utils = new AssistUtils(mContext);
12134            return utils.showSessionForActiveService(args,
12135                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12136        } finally {
12137            Binder.restoreCallingIdentity(ident);
12138        }
12139    }
12140
12141    @Override
12142    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12143            Bundle receiverExtras,
12144            IBinder activityToken, boolean focused, boolean newSessionId) {
12145        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12146                activityToken, focused, newSessionId,
12147                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12148                != null;
12149    }
12150
12151    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12152            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12153            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12154        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12155                "enqueueAssistContext()");
12156        synchronized (this) {
12157            ActivityRecord activity = getFocusedStack().topActivity();
12158            if (activity == null) {
12159                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12160                return null;
12161            }
12162            if (activity.app == null || activity.app.thread == null) {
12163                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12164                return null;
12165            }
12166            if (focused) {
12167                if (activityToken != null) {
12168                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12169                    if (activity != caller) {
12170                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12171                                + " is not current top " + activity);
12172                        return null;
12173                    }
12174                }
12175            } else {
12176                activity = ActivityRecord.forTokenLocked(activityToken);
12177                if (activity == null) {
12178                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12179                            + " couldn't be found");
12180                    return null;
12181                }
12182            }
12183
12184            PendingAssistExtras pae;
12185            Bundle extras = new Bundle();
12186            if (args != null) {
12187                extras.putAll(args);
12188            }
12189            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12190            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12191            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12192                    userHandle);
12193            // Increment the sessionId if necessary
12194            if (newSessionId) {
12195                mViSessionId++;
12196            }
12197            try {
12198                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12199                        requestType, mViSessionId);
12200                mPendingAssistExtras.add(pae);
12201                mUiHandler.postDelayed(pae, timeout);
12202            } catch (RemoteException e) {
12203                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12204                return null;
12205            }
12206            return pae;
12207        }
12208    }
12209
12210    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12211        IResultReceiver receiver;
12212        synchronized (this) {
12213            mPendingAssistExtras.remove(pae);
12214            receiver = pae.receiver;
12215        }
12216        if (receiver != null) {
12217            // Caller wants result sent back to them.
12218            Bundle sendBundle = new Bundle();
12219            // At least return the receiver extras
12220            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12221                    pae.receiverExtras);
12222            try {
12223                pae.receiver.send(0, sendBundle);
12224            } catch (RemoteException e) {
12225            }
12226        }
12227    }
12228
12229    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12230        if (result != null) {
12231            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12232        }
12233        if (pae.hint != null) {
12234            pae.extras.putBoolean(pae.hint, true);
12235        }
12236    }
12237
12238    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12239            AssistContent content, Uri referrer) {
12240        PendingAssistExtras pae = (PendingAssistExtras)token;
12241        synchronized (pae) {
12242            pae.result = extras;
12243            pae.structure = structure;
12244            pae.content = content;
12245            if (referrer != null) {
12246                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12247            }
12248            pae.haveResult = true;
12249            pae.notifyAll();
12250            if (pae.intent == null && pae.receiver == null) {
12251                // Caller is just waiting for the result.
12252                return;
12253            }
12254        }
12255
12256        // We are now ready to launch the assist activity.
12257        IResultReceiver sendReceiver = null;
12258        Bundle sendBundle = null;
12259        synchronized (this) {
12260            buildAssistBundleLocked(pae, extras);
12261            boolean exists = mPendingAssistExtras.remove(pae);
12262            mUiHandler.removeCallbacks(pae);
12263            if (!exists) {
12264                // Timed out.
12265                return;
12266            }
12267            if ((sendReceiver=pae.receiver) != null) {
12268                // Caller wants result sent back to them.
12269                sendBundle = new Bundle();
12270                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12271                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12272                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12273                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12274                        pae.receiverExtras);
12275            }
12276        }
12277        if (sendReceiver != null) {
12278            try {
12279                sendReceiver.send(0, sendBundle);
12280            } catch (RemoteException e) {
12281            }
12282            return;
12283        }
12284
12285        long ident = Binder.clearCallingIdentity();
12286        try {
12287            pae.intent.replaceExtras(pae.extras);
12288            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12289                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12290                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12291            closeSystemDialogs("assist");
12292            try {
12293                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12294            } catch (ActivityNotFoundException e) {
12295                Slog.w(TAG, "No activity to handle assist action.", e);
12296            }
12297        } finally {
12298            Binder.restoreCallingIdentity(ident);
12299        }
12300    }
12301
12302    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12303            Bundle args) {
12304        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12305                true /* focused */, true /* newSessionId */,
12306                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12307    }
12308
12309    public void registerProcessObserver(IProcessObserver observer) {
12310        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12311                "registerProcessObserver()");
12312        synchronized (this) {
12313            mProcessObservers.register(observer);
12314        }
12315    }
12316
12317    @Override
12318    public void unregisterProcessObserver(IProcessObserver observer) {
12319        synchronized (this) {
12320            mProcessObservers.unregister(observer);
12321        }
12322    }
12323
12324    @Override
12325    public void registerUidObserver(IUidObserver observer, int which) {
12326        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12327                "registerUidObserver()");
12328        synchronized (this) {
12329            mUidObservers.register(observer, which);
12330        }
12331    }
12332
12333    @Override
12334    public void unregisterUidObserver(IUidObserver observer) {
12335        synchronized (this) {
12336            mUidObservers.unregister(observer);
12337        }
12338    }
12339
12340    @Override
12341    public boolean convertFromTranslucent(IBinder token) {
12342        final long origId = Binder.clearCallingIdentity();
12343        try {
12344            synchronized (this) {
12345                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12346                if (r == null) {
12347                    return false;
12348                }
12349                final boolean translucentChanged = r.changeWindowTranslucency(true);
12350                if (translucentChanged) {
12351                    r.task.stack.releaseBackgroundResources(r);
12352                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12353                }
12354                mWindowManager.setAppFullscreen(token, true);
12355                return translucentChanged;
12356            }
12357        } finally {
12358            Binder.restoreCallingIdentity(origId);
12359        }
12360    }
12361
12362    @Override
12363    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12364        final long origId = Binder.clearCallingIdentity();
12365        try {
12366            synchronized (this) {
12367                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12368                if (r == null) {
12369                    return false;
12370                }
12371                int index = r.task.mActivities.lastIndexOf(r);
12372                if (index > 0) {
12373                    ActivityRecord under = r.task.mActivities.get(index - 1);
12374                    under.returningOptions = options;
12375                }
12376                final boolean translucentChanged = r.changeWindowTranslucency(false);
12377                if (translucentChanged) {
12378                    r.task.stack.convertActivityToTranslucent(r);
12379                }
12380                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12381                mWindowManager.setAppFullscreen(token, false);
12382                return translucentChanged;
12383            }
12384        } finally {
12385            Binder.restoreCallingIdentity(origId);
12386        }
12387    }
12388
12389    @Override
12390    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12391        final long origId = Binder.clearCallingIdentity();
12392        try {
12393            synchronized (this) {
12394                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12395                if (r != null) {
12396                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12397                }
12398            }
12399            return false;
12400        } finally {
12401            Binder.restoreCallingIdentity(origId);
12402        }
12403    }
12404
12405    @Override
12406    public boolean isBackgroundVisibleBehind(IBinder token) {
12407        final long origId = Binder.clearCallingIdentity();
12408        try {
12409            synchronized (this) {
12410                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12411                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12412                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12413                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12414                return visible;
12415            }
12416        } finally {
12417            Binder.restoreCallingIdentity(origId);
12418        }
12419    }
12420
12421    @Override
12422    public ActivityOptions getActivityOptions(IBinder token) {
12423        final long origId = Binder.clearCallingIdentity();
12424        try {
12425            synchronized (this) {
12426                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12427                if (r != null) {
12428                    final ActivityOptions activityOptions = r.pendingOptions;
12429                    r.pendingOptions = null;
12430                    return activityOptions;
12431                }
12432                return null;
12433            }
12434        } finally {
12435            Binder.restoreCallingIdentity(origId);
12436        }
12437    }
12438
12439    @Override
12440    public void setImmersive(IBinder token, boolean immersive) {
12441        synchronized(this) {
12442            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12443            if (r == null) {
12444                throw new IllegalArgumentException();
12445            }
12446            r.immersive = immersive;
12447
12448            // update associated state if we're frontmost
12449            if (r == mFocusedActivity) {
12450                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12451                applyUpdateLockStateLocked(r);
12452            }
12453        }
12454    }
12455
12456    @Override
12457    public boolean isImmersive(IBinder token) {
12458        synchronized (this) {
12459            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12460            if (r == null) {
12461                throw new IllegalArgumentException();
12462            }
12463            return r.immersive;
12464        }
12465    }
12466
12467    @Override
12468    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12469        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12470            throw new UnsupportedOperationException("VR mode not supported on this device!");
12471        }
12472
12473        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12474
12475        ActivityRecord r;
12476        synchronized (this) {
12477            r = ActivityRecord.isInStackLocked(token);
12478        }
12479
12480        if (r == null) {
12481            throw new IllegalArgumentException();
12482        }
12483
12484        int err;
12485        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12486                VrManagerInternal.NO_ERROR) {
12487            return err;
12488        }
12489
12490        synchronized(this) {
12491            r.requestedVrComponent = (enabled) ? packageName : null;
12492
12493            // Update associated state if this activity is currently focused
12494            if (r == mFocusedActivity) {
12495                applyUpdateVrModeLocked(r);
12496            }
12497            return 0;
12498        }
12499    }
12500
12501    @Override
12502    public boolean isVrModePackageEnabled(ComponentName packageName) {
12503        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12504            throw new UnsupportedOperationException("VR mode not supported on this device!");
12505        }
12506
12507        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12508
12509        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12510                VrManagerInternal.NO_ERROR;
12511    }
12512
12513    public boolean isTopActivityImmersive() {
12514        enforceNotIsolatedCaller("startActivity");
12515        synchronized (this) {
12516            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12517            return (r != null) ? r.immersive : false;
12518        }
12519    }
12520
12521    @Override
12522    public boolean isTopOfTask(IBinder token) {
12523        synchronized (this) {
12524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12525            if (r == null) {
12526                throw new IllegalArgumentException();
12527            }
12528            return r.task.getTopActivity() == r;
12529        }
12530    }
12531
12532    public final void enterSafeMode() {
12533        synchronized(this) {
12534            // It only makes sense to do this before the system is ready
12535            // and started launching other packages.
12536            if (!mSystemReady) {
12537                try {
12538                    AppGlobals.getPackageManager().enterSafeMode();
12539                } catch (RemoteException e) {
12540                }
12541            }
12542
12543            mSafeMode = true;
12544        }
12545    }
12546
12547    public final void showSafeModeOverlay() {
12548        View v = LayoutInflater.from(mContext).inflate(
12549                com.android.internal.R.layout.safe_mode, null);
12550        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12551        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12552        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12553        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12554        lp.gravity = Gravity.BOTTOM | Gravity.START;
12555        lp.format = v.getBackground().getOpacity();
12556        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12557                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12558        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12559        ((WindowManager)mContext.getSystemService(
12560                Context.WINDOW_SERVICE)).addView(v, lp);
12561    }
12562
12563    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12564        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12565            return;
12566        }
12567        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12568        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12569        synchronized (stats) {
12570            if (mBatteryStatsService.isOnBattery()) {
12571                mBatteryStatsService.enforceCallingPermission();
12572                int MY_UID = Binder.getCallingUid();
12573                final int uid;
12574                if (sender == null) {
12575                    uid = sourceUid;
12576                } else {
12577                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12578                }
12579                BatteryStatsImpl.Uid.Pkg pkg =
12580                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12581                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12582                pkg.noteWakeupAlarmLocked(tag);
12583            }
12584        }
12585    }
12586
12587    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12588        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12589            return;
12590        }
12591        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12592        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12593        synchronized (stats) {
12594            mBatteryStatsService.enforceCallingPermission();
12595            int MY_UID = Binder.getCallingUid();
12596            final int uid;
12597            if (sender == null) {
12598                uid = sourceUid;
12599            } else {
12600                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12601            }
12602            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12603        }
12604    }
12605
12606    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12607        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12608            return;
12609        }
12610        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12611        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12612        synchronized (stats) {
12613            mBatteryStatsService.enforceCallingPermission();
12614            int MY_UID = Binder.getCallingUid();
12615            final int uid;
12616            if (sender == null) {
12617                uid = sourceUid;
12618            } else {
12619                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12620            }
12621            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12622        }
12623    }
12624
12625    public boolean killPids(int[] pids, String pReason, boolean secure) {
12626        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12627            throw new SecurityException("killPids only available to the system");
12628        }
12629        String reason = (pReason == null) ? "Unknown" : pReason;
12630        // XXX Note: don't acquire main activity lock here, because the window
12631        // manager calls in with its locks held.
12632
12633        boolean killed = false;
12634        synchronized (mPidsSelfLocked) {
12635            int worstType = 0;
12636            for (int i=0; i<pids.length; i++) {
12637                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12638                if (proc != null) {
12639                    int type = proc.setAdj;
12640                    if (type > worstType) {
12641                        worstType = type;
12642                    }
12643                }
12644            }
12645
12646            // If the worst oom_adj is somewhere in the cached proc LRU range,
12647            // then constrain it so we will kill all cached procs.
12648            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12649                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12650                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12651            }
12652
12653            // If this is not a secure call, don't let it kill processes that
12654            // are important.
12655            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12656                worstType = ProcessList.SERVICE_ADJ;
12657            }
12658
12659            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12660            for (int i=0; i<pids.length; i++) {
12661                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12662                if (proc == null) {
12663                    continue;
12664                }
12665                int adj = proc.setAdj;
12666                if (adj >= worstType && !proc.killedByAm) {
12667                    proc.kill(reason, true);
12668                    killed = true;
12669                }
12670            }
12671        }
12672        return killed;
12673    }
12674
12675    @Override
12676    public void killUid(int appId, int userId, String reason) {
12677        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12678        synchronized (this) {
12679            final long identity = Binder.clearCallingIdentity();
12680            try {
12681                killPackageProcessesLocked(null, appId, userId,
12682                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12683                        reason != null ? reason : "kill uid");
12684            } finally {
12685                Binder.restoreCallingIdentity(identity);
12686            }
12687        }
12688    }
12689
12690    @Override
12691    public boolean killProcessesBelowForeground(String reason) {
12692        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12693            throw new SecurityException("killProcessesBelowForeground() only available to system");
12694        }
12695
12696        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12697    }
12698
12699    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12700        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12701            throw new SecurityException("killProcessesBelowAdj() only available to system");
12702        }
12703
12704        boolean killed = false;
12705        synchronized (mPidsSelfLocked) {
12706            final int size = mPidsSelfLocked.size();
12707            for (int i = 0; i < size; i++) {
12708                final int pid = mPidsSelfLocked.keyAt(i);
12709                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12710                if (proc == null) continue;
12711
12712                final int adj = proc.setAdj;
12713                if (adj > belowAdj && !proc.killedByAm) {
12714                    proc.kill(reason, true);
12715                    killed = true;
12716                }
12717            }
12718        }
12719        return killed;
12720    }
12721
12722    @Override
12723    public void hang(final IBinder who, boolean allowRestart) {
12724        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12725                != PackageManager.PERMISSION_GRANTED) {
12726            throw new SecurityException("Requires permission "
12727                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12728        }
12729
12730        final IBinder.DeathRecipient death = new DeathRecipient() {
12731            @Override
12732            public void binderDied() {
12733                synchronized (this) {
12734                    notifyAll();
12735                }
12736            }
12737        };
12738
12739        try {
12740            who.linkToDeath(death, 0);
12741        } catch (RemoteException e) {
12742            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12743            return;
12744        }
12745
12746        synchronized (this) {
12747            Watchdog.getInstance().setAllowRestart(allowRestart);
12748            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12749            synchronized (death) {
12750                while (who.isBinderAlive()) {
12751                    try {
12752                        death.wait();
12753                    } catch (InterruptedException e) {
12754                    }
12755                }
12756            }
12757            Watchdog.getInstance().setAllowRestart(true);
12758        }
12759    }
12760
12761    @Override
12762    public void restart() {
12763        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12764                != PackageManager.PERMISSION_GRANTED) {
12765            throw new SecurityException("Requires permission "
12766                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12767        }
12768
12769        Log.i(TAG, "Sending shutdown broadcast...");
12770
12771        BroadcastReceiver br = new BroadcastReceiver() {
12772            @Override public void onReceive(Context context, Intent intent) {
12773                // Now the broadcast is done, finish up the low-level shutdown.
12774                Log.i(TAG, "Shutting down activity manager...");
12775                shutdown(10000);
12776                Log.i(TAG, "Shutdown complete, restarting!");
12777                Process.killProcess(Process.myPid());
12778                System.exit(10);
12779            }
12780        };
12781
12782        // First send the high-level shut down broadcast.
12783        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12784        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12785        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12786        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12787        mContext.sendOrderedBroadcastAsUser(intent,
12788                UserHandle.ALL, null, br, mHandler, 0, null, null);
12789        */
12790        br.onReceive(mContext, intent);
12791    }
12792
12793    private long getLowRamTimeSinceIdle(long now) {
12794        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12795    }
12796
12797    @Override
12798    public void performIdleMaintenance() {
12799        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12800                != PackageManager.PERMISSION_GRANTED) {
12801            throw new SecurityException("Requires permission "
12802                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12803        }
12804
12805        synchronized (this) {
12806            final long now = SystemClock.uptimeMillis();
12807            final long timeSinceLastIdle = now - mLastIdleTime;
12808            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12809            mLastIdleTime = now;
12810            mLowRamTimeSinceLastIdle = 0;
12811            if (mLowRamStartTime != 0) {
12812                mLowRamStartTime = now;
12813            }
12814
12815            StringBuilder sb = new StringBuilder(128);
12816            sb.append("Idle maintenance over ");
12817            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12818            sb.append(" low RAM for ");
12819            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12820            Slog.i(TAG, sb.toString());
12821
12822            // If at least 1/3 of our time since the last idle period has been spent
12823            // with RAM low, then we want to kill processes.
12824            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12825
12826            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12827                ProcessRecord proc = mLruProcesses.get(i);
12828                if (proc.notCachedSinceIdle) {
12829                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12830                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12831                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12832                        if (doKilling && proc.initialIdlePss != 0
12833                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12834                            sb = new StringBuilder(128);
12835                            sb.append("Kill");
12836                            sb.append(proc.processName);
12837                            sb.append(" in idle maint: pss=");
12838                            sb.append(proc.lastPss);
12839                            sb.append(", swapPss=");
12840                            sb.append(proc.lastSwapPss);
12841                            sb.append(", initialPss=");
12842                            sb.append(proc.initialIdlePss);
12843                            sb.append(", period=");
12844                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12845                            sb.append(", lowRamPeriod=");
12846                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12847                            Slog.wtfQuiet(TAG, sb.toString());
12848                            proc.kill("idle maint (pss " + proc.lastPss
12849                                    + " from " + proc.initialIdlePss + ")", true);
12850                        }
12851                    }
12852                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12853                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12854                    proc.notCachedSinceIdle = true;
12855                    proc.initialIdlePss = 0;
12856                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12857                            mTestPssMode, isSleepingLocked(), now);
12858                }
12859            }
12860
12861            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12862            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12863        }
12864    }
12865
12866    @Override
12867    public void sendIdleJobTrigger() {
12868        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12869                != PackageManager.PERMISSION_GRANTED) {
12870            throw new SecurityException("Requires permission "
12871                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12872        }
12873
12874        final long ident = Binder.clearCallingIdentity();
12875        try {
12876            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12877                    .setPackage("android")
12878                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12879            broadcastIntent(null, intent, null, null, 0, null, null, null,
12880                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12881        } finally {
12882            Binder.restoreCallingIdentity(ident);
12883        }
12884    }
12885
12886    private void retrieveSettings() {
12887        final ContentResolver resolver = mContext.getContentResolver();
12888        final boolean freeformWindowManagement =
12889                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12890                        || Settings.Global.getInt(
12891                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12892        final boolean supportsPictureInPicture =
12893                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12894
12895        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12896        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12897        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12898        final boolean alwaysFinishActivities =
12899                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12900        final boolean lenientBackgroundCheck =
12901                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12902        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12903        final boolean forceResizable = Settings.Global.getInt(
12904                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12905        final boolean supportsLeanbackOnly =
12906                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12907
12908        // Transfer any global setting for forcing RTL layout, into a System Property
12909        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12910
12911        final Configuration configuration = new Configuration();
12912        Settings.System.getConfiguration(resolver, configuration);
12913        if (forceRtl) {
12914            // This will take care of setting the correct layout direction flags
12915            configuration.setLayoutDirection(configuration.locale);
12916        }
12917
12918        synchronized (this) {
12919            mDebugApp = mOrigDebugApp = debugApp;
12920            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12921            mAlwaysFinishActivities = alwaysFinishActivities;
12922            mLenientBackgroundCheck = lenientBackgroundCheck;
12923            mSupportsLeanbackOnly = supportsLeanbackOnly;
12924            mForceResizableActivities = forceResizable;
12925            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12926            if (supportsMultiWindow || forceResizable) {
12927                mSupportsMultiWindow = true;
12928                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12929                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12930            } else {
12931                mSupportsMultiWindow = false;
12932                mSupportsFreeformWindowManagement = false;
12933                mSupportsPictureInPicture = false;
12934            }
12935            // This happens before any activities are started, so we can
12936            // change mConfiguration in-place.
12937            updateConfigurationLocked(configuration, null, true);
12938            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12939                    "Initial config: " + mConfiguration);
12940
12941            // Load resources only after the current configuration has been set.
12942            final Resources res = mContext.getResources();
12943            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12944            mThumbnailWidth = res.getDimensionPixelSize(
12945                    com.android.internal.R.dimen.thumbnail_width);
12946            mThumbnailHeight = res.getDimensionPixelSize(
12947                    com.android.internal.R.dimen.thumbnail_height);
12948            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12949                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12950            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12951                    com.android.internal.R.string.config_appsNotReportingCrashes));
12952            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12953                mFullscreenThumbnailScale = (float) res
12954                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12955                    (float) mConfiguration.screenWidthDp;
12956            } else {
12957                mFullscreenThumbnailScale = res.getFraction(
12958                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12959            }
12960        }
12961    }
12962
12963    public boolean testIsSystemReady() {
12964        // no need to synchronize(this) just to read & return the value
12965        return mSystemReady;
12966    }
12967
12968    public void systemReady(final Runnable goingCallback) {
12969        synchronized(this) {
12970            if (mSystemReady) {
12971                // If we're done calling all the receivers, run the next "boot phase" passed in
12972                // by the SystemServer
12973                if (goingCallback != null) {
12974                    goingCallback.run();
12975                }
12976                return;
12977            }
12978
12979            mLocalDeviceIdleController
12980                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12981
12982            // Make sure we have the current profile info, since it is needed for security checks.
12983            mUserController.onSystemReady();
12984            mRecentTasks.onSystemReadyLocked();
12985            mAppOpsService.systemReady();
12986            mSystemReady = true;
12987        }
12988
12989        ArrayList<ProcessRecord> procsToKill = null;
12990        synchronized(mPidsSelfLocked) {
12991            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12992                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12993                if (!isAllowedWhileBooting(proc.info)){
12994                    if (procsToKill == null) {
12995                        procsToKill = new ArrayList<ProcessRecord>();
12996                    }
12997                    procsToKill.add(proc);
12998                }
12999            }
13000        }
13001
13002        synchronized(this) {
13003            if (procsToKill != null) {
13004                for (int i=procsToKill.size()-1; i>=0; i--) {
13005                    ProcessRecord proc = procsToKill.get(i);
13006                    Slog.i(TAG, "Removing system update proc: " + proc);
13007                    removeProcessLocked(proc, true, false, "system update done");
13008                }
13009            }
13010
13011            // Now that we have cleaned up any update processes, we
13012            // are ready to start launching real processes and know that
13013            // we won't trample on them any more.
13014            mProcessesReady = true;
13015        }
13016
13017        Slog.i(TAG, "System now ready");
13018        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13019            SystemClock.uptimeMillis());
13020
13021        synchronized(this) {
13022            // Make sure we have no pre-ready processes sitting around.
13023
13024            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13025                ResolveInfo ri = mContext.getPackageManager()
13026                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13027                                STOCK_PM_FLAGS);
13028                CharSequence errorMsg = null;
13029                if (ri != null) {
13030                    ActivityInfo ai = ri.activityInfo;
13031                    ApplicationInfo app = ai.applicationInfo;
13032                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13033                        mTopAction = Intent.ACTION_FACTORY_TEST;
13034                        mTopData = null;
13035                        mTopComponent = new ComponentName(app.packageName,
13036                                ai.name);
13037                    } else {
13038                        errorMsg = mContext.getResources().getText(
13039                                com.android.internal.R.string.factorytest_not_system);
13040                    }
13041                } else {
13042                    errorMsg = mContext.getResources().getText(
13043                            com.android.internal.R.string.factorytest_no_action);
13044                }
13045                if (errorMsg != null) {
13046                    mTopAction = null;
13047                    mTopData = null;
13048                    mTopComponent = null;
13049                    Message msg = Message.obtain();
13050                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13051                    msg.getData().putCharSequence("msg", errorMsg);
13052                    mUiHandler.sendMessage(msg);
13053                }
13054            }
13055        }
13056
13057        retrieveSettings();
13058        final int currentUserId;
13059        synchronized (this) {
13060            currentUserId = mUserController.getCurrentUserIdLocked();
13061            readGrantedUriPermissionsLocked();
13062        }
13063
13064        if (goingCallback != null) goingCallback.run();
13065
13066        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13067                Integer.toString(currentUserId), currentUserId);
13068        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13069                Integer.toString(currentUserId), currentUserId);
13070        mSystemServiceManager.startUser(currentUserId);
13071
13072        synchronized (this) {
13073            // Only start up encryption-aware persistent apps; once user is
13074            // unlocked we'll come back around and start unaware apps
13075            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13076
13077            // Start up initial activity.
13078            mBooting = true;
13079            // Enable home activity for system user, so that the system can always boot
13080            if (UserManager.isSplitSystemUser()) {
13081                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13082                try {
13083                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13084                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13085                            UserHandle.USER_SYSTEM);
13086                } catch (RemoteException e) {
13087                    throw e.rethrowAsRuntimeException();
13088                }
13089            }
13090            startHomeActivityLocked(currentUserId, "systemReady");
13091
13092            try {
13093                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13094                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13095                            + " data partition or your device will be unstable.");
13096                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13097                }
13098            } catch (RemoteException e) {
13099            }
13100
13101            if (!Build.isBuildConsistent()) {
13102                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13103                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13104            }
13105
13106            long ident = Binder.clearCallingIdentity();
13107            try {
13108                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13109                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13110                        | Intent.FLAG_RECEIVER_FOREGROUND);
13111                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13112                broadcastIntentLocked(null, null, intent,
13113                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13114                        null, false, false, MY_PID, Process.SYSTEM_UID,
13115                        currentUserId);
13116                intent = new Intent(Intent.ACTION_USER_STARTING);
13117                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13118                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13119                broadcastIntentLocked(null, null, intent,
13120                        null, new IIntentReceiver.Stub() {
13121                            @Override
13122                            public void performReceive(Intent intent, int resultCode, String data,
13123                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13124                                    throws RemoteException {
13125                            }
13126                        }, 0, null, null,
13127                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13128                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13129            } catch (Throwable t) {
13130                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13131            } finally {
13132                Binder.restoreCallingIdentity(ident);
13133            }
13134            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13135            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13136        }
13137    }
13138
13139    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13140        synchronized (this) {
13141            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13142        }
13143    }
13144
13145    void skipCurrentReceiverLocked(ProcessRecord app) {
13146        for (BroadcastQueue queue : mBroadcastQueues) {
13147            queue.skipCurrentReceiverLocked(app);
13148        }
13149    }
13150
13151    /**
13152     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13153     * The application process will exit immediately after this call returns.
13154     * @param app object of the crashing app, null for the system server
13155     * @param crashInfo describing the exception
13156     */
13157    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13158        ProcessRecord r = findAppProcess(app, "Crash");
13159        final String processName = app == null ? "system_server"
13160                : (r == null ? "unknown" : r.processName);
13161
13162        handleApplicationCrashInner("crash", r, processName, crashInfo);
13163    }
13164
13165    /* Native crash reporting uses this inner version because it needs to be somewhat
13166     * decoupled from the AM-managed cleanup lifecycle
13167     */
13168    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13169            ApplicationErrorReport.CrashInfo crashInfo) {
13170        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13171                UserHandle.getUserId(Binder.getCallingUid()), processName,
13172                r == null ? -1 : r.info.flags,
13173                crashInfo.exceptionClassName,
13174                crashInfo.exceptionMessage,
13175                crashInfo.throwFileName,
13176                crashInfo.throwLineNumber);
13177
13178        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13179
13180        mAppErrors.crashApplication(r, crashInfo);
13181    }
13182
13183    public void handleApplicationStrictModeViolation(
13184            IBinder app,
13185            int violationMask,
13186            StrictMode.ViolationInfo info) {
13187        ProcessRecord r = findAppProcess(app, "StrictMode");
13188        if (r == null) {
13189            return;
13190        }
13191
13192        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13193            Integer stackFingerprint = info.hashCode();
13194            boolean logIt = true;
13195            synchronized (mAlreadyLoggedViolatedStacks) {
13196                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13197                    logIt = false;
13198                    // TODO: sub-sample into EventLog for these, with
13199                    // the info.durationMillis?  Then we'd get
13200                    // the relative pain numbers, without logging all
13201                    // the stack traces repeatedly.  We'd want to do
13202                    // likewise in the client code, which also does
13203                    // dup suppression, before the Binder call.
13204                } else {
13205                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13206                        mAlreadyLoggedViolatedStacks.clear();
13207                    }
13208                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13209                }
13210            }
13211            if (logIt) {
13212                logStrictModeViolationToDropBox(r, info);
13213            }
13214        }
13215
13216        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13217            AppErrorResult result = new AppErrorResult();
13218            synchronized (this) {
13219                final long origId = Binder.clearCallingIdentity();
13220
13221                Message msg = Message.obtain();
13222                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13223                HashMap<String, Object> data = new HashMap<String, Object>();
13224                data.put("result", result);
13225                data.put("app", r);
13226                data.put("violationMask", violationMask);
13227                data.put("info", info);
13228                msg.obj = data;
13229                mUiHandler.sendMessage(msg);
13230
13231                Binder.restoreCallingIdentity(origId);
13232            }
13233            int res = result.get();
13234            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13235        }
13236    }
13237
13238    // Depending on the policy in effect, there could be a bunch of
13239    // these in quick succession so we try to batch these together to
13240    // minimize disk writes, number of dropbox entries, and maximize
13241    // compression, by having more fewer, larger records.
13242    private void logStrictModeViolationToDropBox(
13243            ProcessRecord process,
13244            StrictMode.ViolationInfo info) {
13245        if (info == null) {
13246            return;
13247        }
13248        final boolean isSystemApp = process == null ||
13249                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13250                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13251        final String processName = process == null ? "unknown" : process.processName;
13252        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13253        final DropBoxManager dbox = (DropBoxManager)
13254                mContext.getSystemService(Context.DROPBOX_SERVICE);
13255
13256        // Exit early if the dropbox isn't configured to accept this report type.
13257        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13258
13259        boolean bufferWasEmpty;
13260        boolean needsFlush;
13261        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13262        synchronized (sb) {
13263            bufferWasEmpty = sb.length() == 0;
13264            appendDropBoxProcessHeaders(process, processName, sb);
13265            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13266            sb.append("System-App: ").append(isSystemApp).append("\n");
13267            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13268            if (info.violationNumThisLoop != 0) {
13269                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13270            }
13271            if (info.numAnimationsRunning != 0) {
13272                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13273            }
13274            if (info.broadcastIntentAction != null) {
13275                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13276            }
13277            if (info.durationMillis != -1) {
13278                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13279            }
13280            if (info.numInstances != -1) {
13281                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13282            }
13283            if (info.tags != null) {
13284                for (String tag : info.tags) {
13285                    sb.append("Span-Tag: ").append(tag).append("\n");
13286                }
13287            }
13288            sb.append("\n");
13289            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13290                sb.append(info.crashInfo.stackTrace);
13291                sb.append("\n");
13292            }
13293            if (info.message != null) {
13294                sb.append(info.message);
13295                sb.append("\n");
13296            }
13297
13298            // Only buffer up to ~64k.  Various logging bits truncate
13299            // things at 128k.
13300            needsFlush = (sb.length() > 64 * 1024);
13301        }
13302
13303        // Flush immediately if the buffer's grown too large, or this
13304        // is a non-system app.  Non-system apps are isolated with a
13305        // different tag & policy and not batched.
13306        //
13307        // Batching is useful during internal testing with
13308        // StrictMode settings turned up high.  Without batching,
13309        // thousands of separate files could be created on boot.
13310        if (!isSystemApp || needsFlush) {
13311            new Thread("Error dump: " + dropboxTag) {
13312                @Override
13313                public void run() {
13314                    String report;
13315                    synchronized (sb) {
13316                        report = sb.toString();
13317                        sb.delete(0, sb.length());
13318                        sb.trimToSize();
13319                    }
13320                    if (report.length() != 0) {
13321                        dbox.addText(dropboxTag, report);
13322                    }
13323                }
13324            }.start();
13325            return;
13326        }
13327
13328        // System app batching:
13329        if (!bufferWasEmpty) {
13330            // An existing dropbox-writing thread is outstanding, so
13331            // we don't need to start it up.  The existing thread will
13332            // catch the buffer appends we just did.
13333            return;
13334        }
13335
13336        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13337        // (After this point, we shouldn't access AMS internal data structures.)
13338        new Thread("Error dump: " + dropboxTag) {
13339            @Override
13340            public void run() {
13341                // 5 second sleep to let stacks arrive and be batched together
13342                try {
13343                    Thread.sleep(5000);  // 5 seconds
13344                } catch (InterruptedException e) {}
13345
13346                String errorReport;
13347                synchronized (mStrictModeBuffer) {
13348                    errorReport = mStrictModeBuffer.toString();
13349                    if (errorReport.length() == 0) {
13350                        return;
13351                    }
13352                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13353                    mStrictModeBuffer.trimToSize();
13354                }
13355                dbox.addText(dropboxTag, errorReport);
13356            }
13357        }.start();
13358    }
13359
13360    /**
13361     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13362     * @param app object of the crashing app, null for the system server
13363     * @param tag reported by the caller
13364     * @param system whether this wtf is coming from the system
13365     * @param crashInfo describing the context of the error
13366     * @return true if the process should exit immediately (WTF is fatal)
13367     */
13368    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13369            final ApplicationErrorReport.CrashInfo crashInfo) {
13370        final int callingUid = Binder.getCallingUid();
13371        final int callingPid = Binder.getCallingPid();
13372
13373        if (system) {
13374            // If this is coming from the system, we could very well have low-level
13375            // system locks held, so we want to do this all asynchronously.  And we
13376            // never want this to become fatal, so there is that too.
13377            mHandler.post(new Runnable() {
13378                @Override public void run() {
13379                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13380                }
13381            });
13382            return false;
13383        }
13384
13385        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13386                crashInfo);
13387
13388        if (r != null && r.pid != Process.myPid() &&
13389                Settings.Global.getInt(mContext.getContentResolver(),
13390                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13391            mAppErrors.crashApplication(r, crashInfo);
13392            return true;
13393        } else {
13394            return false;
13395        }
13396    }
13397
13398    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13399            final ApplicationErrorReport.CrashInfo crashInfo) {
13400        final ProcessRecord r = findAppProcess(app, "WTF");
13401        final String processName = app == null ? "system_server"
13402                : (r == null ? "unknown" : r.processName);
13403
13404        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13405                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13406
13407        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13408
13409        return r;
13410    }
13411
13412    /**
13413     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13414     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13415     */
13416    private ProcessRecord findAppProcess(IBinder app, String reason) {
13417        if (app == null) {
13418            return null;
13419        }
13420
13421        synchronized (this) {
13422            final int NP = mProcessNames.getMap().size();
13423            for (int ip=0; ip<NP; ip++) {
13424                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13425                final int NA = apps.size();
13426                for (int ia=0; ia<NA; ia++) {
13427                    ProcessRecord p = apps.valueAt(ia);
13428                    if (p.thread != null && p.thread.asBinder() == app) {
13429                        return p;
13430                    }
13431                }
13432            }
13433
13434            Slog.w(TAG, "Can't find mystery application for " + reason
13435                    + " from pid=" + Binder.getCallingPid()
13436                    + " uid=" + Binder.getCallingUid() + ": " + app);
13437            return null;
13438        }
13439    }
13440
13441    /**
13442     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13443     * to append various headers to the dropbox log text.
13444     */
13445    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13446            StringBuilder sb) {
13447        // Watchdog thread ends up invoking this function (with
13448        // a null ProcessRecord) to add the stack file to dropbox.
13449        // Do not acquire a lock on this (am) in such cases, as it
13450        // could cause a potential deadlock, if and when watchdog
13451        // is invoked due to unavailability of lock on am and it
13452        // would prevent watchdog from killing system_server.
13453        if (process == null) {
13454            sb.append("Process: ").append(processName).append("\n");
13455            return;
13456        }
13457        // Note: ProcessRecord 'process' is guarded by the service
13458        // instance.  (notably process.pkgList, which could otherwise change
13459        // concurrently during execution of this method)
13460        synchronized (this) {
13461            sb.append("Process: ").append(processName).append("\n");
13462            int flags = process.info.flags;
13463            IPackageManager pm = AppGlobals.getPackageManager();
13464            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13465            for (int ip=0; ip<process.pkgList.size(); ip++) {
13466                String pkg = process.pkgList.keyAt(ip);
13467                sb.append("Package: ").append(pkg);
13468                try {
13469                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13470                    if (pi != null) {
13471                        sb.append(" v").append(pi.versionCode);
13472                        if (pi.versionName != null) {
13473                            sb.append(" (").append(pi.versionName).append(")");
13474                        }
13475                    }
13476                } catch (RemoteException e) {
13477                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13478                }
13479                sb.append("\n");
13480            }
13481        }
13482    }
13483
13484    private static String processClass(ProcessRecord process) {
13485        if (process == null || process.pid == MY_PID) {
13486            return "system_server";
13487        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13488            return "system_app";
13489        } else {
13490            return "data_app";
13491        }
13492    }
13493
13494    private volatile long mWtfClusterStart;
13495    private volatile int mWtfClusterCount;
13496
13497    /**
13498     * Write a description of an error (crash, WTF, ANR) to the drop box.
13499     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13500     * @param process which caused the error, null means the system server
13501     * @param activity which triggered the error, null if unknown
13502     * @param parent activity related to the error, null if unknown
13503     * @param subject line related to the error, null if absent
13504     * @param report in long form describing the error, null if absent
13505     * @param logFile to include in the report, null if none
13506     * @param crashInfo giving an application stack trace, null if absent
13507     */
13508    public void addErrorToDropBox(String eventType,
13509            ProcessRecord process, String processName, ActivityRecord activity,
13510            ActivityRecord parent, String subject,
13511            final String report, final File logFile,
13512            final ApplicationErrorReport.CrashInfo crashInfo) {
13513        // NOTE -- this must never acquire the ActivityManagerService lock,
13514        // otherwise the watchdog may be prevented from resetting the system.
13515
13516        final String dropboxTag = processClass(process) + "_" + eventType;
13517        final DropBoxManager dbox = (DropBoxManager)
13518                mContext.getSystemService(Context.DROPBOX_SERVICE);
13519
13520        // Exit early if the dropbox isn't configured to accept this report type.
13521        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13522
13523        // Rate-limit how often we're willing to do the heavy lifting below to
13524        // collect and record logs; currently 5 logs per 10 second period.
13525        final long now = SystemClock.elapsedRealtime();
13526        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13527            mWtfClusterStart = now;
13528            mWtfClusterCount = 1;
13529        } else {
13530            if (mWtfClusterCount++ >= 5) return;
13531        }
13532
13533        final StringBuilder sb = new StringBuilder(1024);
13534        appendDropBoxProcessHeaders(process, processName, sb);
13535        if (process != null) {
13536            sb.append("Foreground: ")
13537                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13538                    .append("\n");
13539        }
13540        if (activity != null) {
13541            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13542        }
13543        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13544            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13545        }
13546        if (parent != null && parent != activity) {
13547            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13548        }
13549        if (subject != null) {
13550            sb.append("Subject: ").append(subject).append("\n");
13551        }
13552        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13553        if (Debug.isDebuggerConnected()) {
13554            sb.append("Debugger: Connected\n");
13555        }
13556        sb.append("\n");
13557
13558        // Do the rest in a worker thread to avoid blocking the caller on I/O
13559        // (After this point, we shouldn't access AMS internal data structures.)
13560        Thread worker = new Thread("Error dump: " + dropboxTag) {
13561            @Override
13562            public void run() {
13563                if (report != null) {
13564                    sb.append(report);
13565                }
13566                if (logFile != null) {
13567                    try {
13568                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13569                                    "\n\n[[TRUNCATED]]"));
13570                    } catch (IOException e) {
13571                        Slog.e(TAG, "Error reading " + logFile, e);
13572                    }
13573                }
13574                if (crashInfo != null && crashInfo.stackTrace != null) {
13575                    sb.append(crashInfo.stackTrace);
13576                }
13577
13578                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13579                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13580                if (lines > 0) {
13581                    sb.append("\n");
13582
13583                    // Merge several logcat streams, and take the last N lines
13584                    InputStreamReader input = null;
13585                    try {
13586                        java.lang.Process logcat = new ProcessBuilder(
13587                                "/system/bin/timeout", "-k", "15s", "10s",
13588                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13589                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13590                                        .redirectErrorStream(true).start();
13591
13592                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13593                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13594                        input = new InputStreamReader(logcat.getInputStream());
13595
13596                        int num;
13597                        char[] buf = new char[8192];
13598                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13599                    } catch (IOException e) {
13600                        Slog.e(TAG, "Error running logcat", e);
13601                    } finally {
13602                        if (input != null) try { input.close(); } catch (IOException e) {}
13603                    }
13604                }
13605
13606                dbox.addText(dropboxTag, sb.toString());
13607            }
13608        };
13609
13610        if (process == null) {
13611            // If process is null, we are being called from some internal code
13612            // and may be about to die -- run this synchronously.
13613            worker.run();
13614        } else {
13615            worker.start();
13616        }
13617    }
13618
13619    @Override
13620    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13621        enforceNotIsolatedCaller("getProcessesInErrorState");
13622        // assume our apps are happy - lazy create the list
13623        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13624
13625        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13626                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13627        int userId = UserHandle.getUserId(Binder.getCallingUid());
13628
13629        synchronized (this) {
13630
13631            // iterate across all processes
13632            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13633                ProcessRecord app = mLruProcesses.get(i);
13634                if (!allUsers && app.userId != userId) {
13635                    continue;
13636                }
13637                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13638                    // This one's in trouble, so we'll generate a report for it
13639                    // crashes are higher priority (in case there's a crash *and* an anr)
13640                    ActivityManager.ProcessErrorStateInfo report = null;
13641                    if (app.crashing) {
13642                        report = app.crashingReport;
13643                    } else if (app.notResponding) {
13644                        report = app.notRespondingReport;
13645                    }
13646
13647                    if (report != null) {
13648                        if (errList == null) {
13649                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13650                        }
13651                        errList.add(report);
13652                    } else {
13653                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13654                                " crashing = " + app.crashing +
13655                                " notResponding = " + app.notResponding);
13656                    }
13657                }
13658            }
13659        }
13660
13661        return errList;
13662    }
13663
13664    static int procStateToImportance(int procState, int memAdj,
13665            ActivityManager.RunningAppProcessInfo currApp) {
13666        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13667        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13668            currApp.lru = memAdj;
13669        } else {
13670            currApp.lru = 0;
13671        }
13672        return imp;
13673    }
13674
13675    private void fillInProcMemInfo(ProcessRecord app,
13676            ActivityManager.RunningAppProcessInfo outInfo) {
13677        outInfo.pid = app.pid;
13678        outInfo.uid = app.info.uid;
13679        if (mHeavyWeightProcess == app) {
13680            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13681        }
13682        if (app.persistent) {
13683            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13684        }
13685        if (app.activities.size() > 0) {
13686            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13687        }
13688        outInfo.lastTrimLevel = app.trimMemoryLevel;
13689        int adj = app.curAdj;
13690        int procState = app.curProcState;
13691        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13692        outInfo.importanceReasonCode = app.adjTypeCode;
13693        outInfo.processState = app.curProcState;
13694    }
13695
13696    @Override
13697    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13698        enforceNotIsolatedCaller("getRunningAppProcesses");
13699
13700        final int callingUid = Binder.getCallingUid();
13701
13702        // Lazy instantiation of list
13703        List<ActivityManager.RunningAppProcessInfo> runList = null;
13704        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13705                callingUid) == PackageManager.PERMISSION_GRANTED;
13706        final int userId = UserHandle.getUserId(callingUid);
13707        final boolean allUids = isGetTasksAllowed(
13708                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13709
13710        synchronized (this) {
13711            // Iterate across all processes
13712            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13713                ProcessRecord app = mLruProcesses.get(i);
13714                if ((!allUsers && app.userId != userId)
13715                        || (!allUids && app.uid != callingUid)) {
13716                    continue;
13717                }
13718                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13719                    // Generate process state info for running application
13720                    ActivityManager.RunningAppProcessInfo currApp =
13721                        new ActivityManager.RunningAppProcessInfo(app.processName,
13722                                app.pid, app.getPackageList());
13723                    fillInProcMemInfo(app, currApp);
13724                    if (app.adjSource instanceof ProcessRecord) {
13725                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13726                        currApp.importanceReasonImportance =
13727                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13728                                        app.adjSourceProcState);
13729                    } else if (app.adjSource instanceof ActivityRecord) {
13730                        ActivityRecord r = (ActivityRecord)app.adjSource;
13731                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13732                    }
13733                    if (app.adjTarget instanceof ComponentName) {
13734                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13735                    }
13736                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13737                    //        + " lru=" + currApp.lru);
13738                    if (runList == null) {
13739                        runList = new ArrayList<>();
13740                    }
13741                    runList.add(currApp);
13742                }
13743            }
13744        }
13745        return runList;
13746    }
13747
13748    @Override
13749    public List<ApplicationInfo> getRunningExternalApplications() {
13750        enforceNotIsolatedCaller("getRunningExternalApplications");
13751        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13752        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13753        if (runningApps != null && runningApps.size() > 0) {
13754            Set<String> extList = new HashSet<String>();
13755            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13756                if (app.pkgList != null) {
13757                    for (String pkg : app.pkgList) {
13758                        extList.add(pkg);
13759                    }
13760                }
13761            }
13762            IPackageManager pm = AppGlobals.getPackageManager();
13763            for (String pkg : extList) {
13764                try {
13765                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13766                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13767                        retList.add(info);
13768                    }
13769                } catch (RemoteException e) {
13770                }
13771            }
13772        }
13773        return retList;
13774    }
13775
13776    @Override
13777    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13778        enforceNotIsolatedCaller("getMyMemoryState");
13779        synchronized (this) {
13780            ProcessRecord proc;
13781            synchronized (mPidsSelfLocked) {
13782                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13783            }
13784            fillInProcMemInfo(proc, outInfo);
13785        }
13786    }
13787
13788    @Override
13789    public int getMemoryTrimLevel() {
13790        enforceNotIsolatedCaller("getMyMemoryState");
13791        synchronized (this) {
13792            return mLastMemoryLevel;
13793        }
13794    }
13795
13796    @Override
13797    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13798            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13799        (new ActivityManagerShellCommand(this, false)).exec(
13800                this, in, out, err, args, resultReceiver);
13801    }
13802
13803    @Override
13804    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13805        if (checkCallingPermission(android.Manifest.permission.DUMP)
13806                != PackageManager.PERMISSION_GRANTED) {
13807            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13808                    + Binder.getCallingPid()
13809                    + ", uid=" + Binder.getCallingUid()
13810                    + " without permission "
13811                    + android.Manifest.permission.DUMP);
13812            return;
13813        }
13814
13815        boolean dumpAll = false;
13816        boolean dumpClient = false;
13817        boolean dumpCheckin = false;
13818        boolean dumpCheckinFormat = false;
13819        String dumpPackage = null;
13820
13821        int opti = 0;
13822        while (opti < args.length) {
13823            String opt = args[opti];
13824            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13825                break;
13826            }
13827            opti++;
13828            if ("-a".equals(opt)) {
13829                dumpAll = true;
13830            } else if ("-c".equals(opt)) {
13831                dumpClient = true;
13832            } else if ("-p".equals(opt)) {
13833                if (opti < args.length) {
13834                    dumpPackage = args[opti];
13835                    opti++;
13836                } else {
13837                    pw.println("Error: -p option requires package argument");
13838                    return;
13839                }
13840                dumpClient = true;
13841            } else if ("--checkin".equals(opt)) {
13842                dumpCheckin = dumpCheckinFormat = true;
13843            } else if ("-C".equals(opt)) {
13844                dumpCheckinFormat = true;
13845            } else if ("-h".equals(opt)) {
13846                ActivityManagerShellCommand.dumpHelp(pw, true);
13847                return;
13848            } else {
13849                pw.println("Unknown argument: " + opt + "; use -h for help");
13850            }
13851        }
13852
13853        long origId = Binder.clearCallingIdentity();
13854        boolean more = false;
13855        // Is the caller requesting to dump a particular piece of data?
13856        if (opti < args.length) {
13857            String cmd = args[opti];
13858            opti++;
13859            if ("activities".equals(cmd) || "a".equals(cmd)) {
13860                synchronized (this) {
13861                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13862                }
13863            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13864                synchronized (this) {
13865                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13866                }
13867            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13868                String[] newArgs;
13869                String name;
13870                if (opti >= args.length) {
13871                    name = null;
13872                    newArgs = EMPTY_STRING_ARRAY;
13873                } else {
13874                    dumpPackage = args[opti];
13875                    opti++;
13876                    newArgs = new String[args.length - opti];
13877                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13878                            args.length - opti);
13879                }
13880                synchronized (this) {
13881                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13882                }
13883            } else if ("broadcast-stats".equals(cmd)) {
13884                String[] newArgs;
13885                String name;
13886                if (opti >= args.length) {
13887                    name = null;
13888                    newArgs = EMPTY_STRING_ARRAY;
13889                } else {
13890                    dumpPackage = args[opti];
13891                    opti++;
13892                    newArgs = new String[args.length - opti];
13893                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13894                            args.length - opti);
13895                }
13896                synchronized (this) {
13897                    if (dumpCheckinFormat) {
13898                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13899                                dumpPackage);
13900                    } else {
13901                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13902                    }
13903                }
13904            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13905                String[] newArgs;
13906                String name;
13907                if (opti >= args.length) {
13908                    name = null;
13909                    newArgs = EMPTY_STRING_ARRAY;
13910                } else {
13911                    dumpPackage = args[opti];
13912                    opti++;
13913                    newArgs = new String[args.length - opti];
13914                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13915                            args.length - opti);
13916                }
13917                synchronized (this) {
13918                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13919                }
13920            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13921                String[] newArgs;
13922                String name;
13923                if (opti >= args.length) {
13924                    name = null;
13925                    newArgs = EMPTY_STRING_ARRAY;
13926                } else {
13927                    dumpPackage = args[opti];
13928                    opti++;
13929                    newArgs = new String[args.length - opti];
13930                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13931                            args.length - opti);
13932                }
13933                synchronized (this) {
13934                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13935                }
13936            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13937                synchronized (this) {
13938                    dumpOomLocked(fd, pw, args, opti, true);
13939                }
13940            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13941                synchronized (this) {
13942                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13943                }
13944            } else if ("provider".equals(cmd)) {
13945                String[] newArgs;
13946                String name;
13947                if (opti >= args.length) {
13948                    name = null;
13949                    newArgs = EMPTY_STRING_ARRAY;
13950                } else {
13951                    name = args[opti];
13952                    opti++;
13953                    newArgs = new String[args.length - opti];
13954                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13955                }
13956                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13957                    pw.println("No providers match: " + name);
13958                    pw.println("Use -h for help.");
13959                }
13960            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13961                synchronized (this) {
13962                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13963                }
13964            } else if ("service".equals(cmd)) {
13965                String[] newArgs;
13966                String name;
13967                if (opti >= args.length) {
13968                    name = null;
13969                    newArgs = EMPTY_STRING_ARRAY;
13970                } else {
13971                    name = args[opti];
13972                    opti++;
13973                    newArgs = new String[args.length - opti];
13974                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13975                            args.length - opti);
13976                }
13977                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13978                    pw.println("No services match: " + name);
13979                    pw.println("Use -h for help.");
13980                }
13981            } else if ("package".equals(cmd)) {
13982                String[] newArgs;
13983                if (opti >= args.length) {
13984                    pw.println("package: no package name specified");
13985                    pw.println("Use -h for help.");
13986                } else {
13987                    dumpPackage = args[opti];
13988                    opti++;
13989                    newArgs = new String[args.length - opti];
13990                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13991                            args.length - opti);
13992                    args = newArgs;
13993                    opti = 0;
13994                    more = true;
13995                }
13996            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13997                synchronized (this) {
13998                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13999                }
14000            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14001                if (dumpClient) {
14002                    ActiveServices.ServiceDumper dumper;
14003                    synchronized (this) {
14004                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14005                                dumpPackage);
14006                    }
14007                    dumper.dumpWithClient();
14008                } else {
14009                    synchronized (this) {
14010                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14011                                dumpPackage).dumpLocked();
14012                    }
14013                }
14014            } else if ("locks".equals(cmd)) {
14015                LockGuard.dump(fd, pw, args);
14016            } else {
14017                // Dumping a single activity?
14018                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14019                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14020                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14021                    if (res < 0) {
14022                        pw.println("Bad activity command, or no activities match: " + cmd);
14023                        pw.println("Use -h for help.");
14024                    }
14025                }
14026            }
14027            if (!more) {
14028                Binder.restoreCallingIdentity(origId);
14029                return;
14030            }
14031        }
14032
14033        // No piece of data specified, dump everything.
14034        if (dumpCheckinFormat) {
14035            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14036        } else if (dumpClient) {
14037            ActiveServices.ServiceDumper sdumper;
14038            synchronized (this) {
14039                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14040                pw.println();
14041                if (dumpAll) {
14042                    pw.println("-------------------------------------------------------------------------------");
14043                }
14044                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14045                pw.println();
14046                if (dumpAll) {
14047                    pw.println("-------------------------------------------------------------------------------");
14048                }
14049                if (dumpAll || dumpPackage != null) {
14050                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14051                    pw.println();
14052                    if (dumpAll) {
14053                        pw.println("-------------------------------------------------------------------------------");
14054                    }
14055                }
14056                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14057                pw.println();
14058                if (dumpAll) {
14059                    pw.println("-------------------------------------------------------------------------------");
14060                }
14061                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14062                pw.println();
14063                if (dumpAll) {
14064                    pw.println("-------------------------------------------------------------------------------");
14065                }
14066                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14067                        dumpPackage);
14068            }
14069            sdumper.dumpWithClient();
14070            pw.println();
14071            synchronized (this) {
14072                if (dumpAll) {
14073                    pw.println("-------------------------------------------------------------------------------");
14074                }
14075                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14076                pw.println();
14077                if (dumpAll) {
14078                    pw.println("-------------------------------------------------------------------------------");
14079                }
14080                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14081                if (mAssociations.size() > 0) {
14082                    pw.println();
14083                    if (dumpAll) {
14084                        pw.println("-------------------------------------------------------------------------------");
14085                    }
14086                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14087                }
14088                pw.println();
14089                if (dumpAll) {
14090                    pw.println("-------------------------------------------------------------------------------");
14091                }
14092                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14093            }
14094
14095        } else {
14096            synchronized (this) {
14097                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14098                pw.println();
14099                if (dumpAll) {
14100                    pw.println("-------------------------------------------------------------------------------");
14101                }
14102                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14103                pw.println();
14104                if (dumpAll) {
14105                    pw.println("-------------------------------------------------------------------------------");
14106                }
14107                if (dumpAll || dumpPackage != null) {
14108                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14109                    pw.println();
14110                    if (dumpAll) {
14111                        pw.println("-------------------------------------------------------------------------------");
14112                    }
14113                }
14114                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14115                pw.println();
14116                if (dumpAll) {
14117                    pw.println("-------------------------------------------------------------------------------");
14118                }
14119                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14120                pw.println();
14121                if (dumpAll) {
14122                    pw.println("-------------------------------------------------------------------------------");
14123                }
14124                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14125                        .dumpLocked();
14126                pw.println();
14127                if (dumpAll) {
14128                    pw.println("-------------------------------------------------------------------------------");
14129                }
14130                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14131                pw.println();
14132                if (dumpAll) {
14133                    pw.println("-------------------------------------------------------------------------------");
14134                }
14135                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14136                if (mAssociations.size() > 0) {
14137                    pw.println();
14138                    if (dumpAll) {
14139                        pw.println("-------------------------------------------------------------------------------");
14140                    }
14141                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14142                }
14143                pw.println();
14144                if (dumpAll) {
14145                    pw.println("-------------------------------------------------------------------------------");
14146                }
14147                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14148            }
14149        }
14150        Binder.restoreCallingIdentity(origId);
14151    }
14152
14153    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14154            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14155        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14156
14157        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14158                dumpPackage);
14159        boolean needSep = printedAnything;
14160
14161        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14162                dumpPackage, needSep, "  mFocusedActivity: ");
14163        if (printed) {
14164            printedAnything = true;
14165            needSep = false;
14166        }
14167
14168        if (dumpPackage == null) {
14169            if (needSep) {
14170                pw.println();
14171            }
14172            needSep = true;
14173            printedAnything = true;
14174            mStackSupervisor.dump(pw, "  ");
14175        }
14176
14177        if (!printedAnything) {
14178            pw.println("  (nothing)");
14179        }
14180    }
14181
14182    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14183            int opti, boolean dumpAll, String dumpPackage) {
14184        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14185
14186        boolean printedAnything = false;
14187
14188        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14189            boolean printedHeader = false;
14190
14191            final int N = mRecentTasks.size();
14192            for (int i=0; i<N; i++) {
14193                TaskRecord tr = mRecentTasks.get(i);
14194                if (dumpPackage != null) {
14195                    if (tr.realActivity == null ||
14196                            !dumpPackage.equals(tr.realActivity)) {
14197                        continue;
14198                    }
14199                }
14200                if (!printedHeader) {
14201                    pw.println("  Recent tasks:");
14202                    printedHeader = true;
14203                    printedAnything = true;
14204                }
14205                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14206                        pw.println(tr);
14207                if (dumpAll) {
14208                    mRecentTasks.get(i).dump(pw, "    ");
14209                }
14210            }
14211        }
14212
14213        if (!printedAnything) {
14214            pw.println("  (nothing)");
14215        }
14216    }
14217
14218    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14219            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14220        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14221
14222        int dumpUid = 0;
14223        if (dumpPackage != null) {
14224            IPackageManager pm = AppGlobals.getPackageManager();
14225            try {
14226                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14227            } catch (RemoteException e) {
14228            }
14229        }
14230
14231        boolean printedAnything = false;
14232
14233        final long now = SystemClock.uptimeMillis();
14234
14235        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14236            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14237                    = mAssociations.valueAt(i1);
14238            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14239                SparseArray<ArrayMap<String, Association>> sourceUids
14240                        = targetComponents.valueAt(i2);
14241                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14242                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14243                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14244                        Association ass = sourceProcesses.valueAt(i4);
14245                        if (dumpPackage != null) {
14246                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14247                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14248                                continue;
14249                            }
14250                        }
14251                        printedAnything = true;
14252                        pw.print("  ");
14253                        pw.print(ass.mTargetProcess);
14254                        pw.print("/");
14255                        UserHandle.formatUid(pw, ass.mTargetUid);
14256                        pw.print(" <- ");
14257                        pw.print(ass.mSourceProcess);
14258                        pw.print("/");
14259                        UserHandle.formatUid(pw, ass.mSourceUid);
14260                        pw.println();
14261                        pw.print("    via ");
14262                        pw.print(ass.mTargetComponent.flattenToShortString());
14263                        pw.println();
14264                        pw.print("    ");
14265                        long dur = ass.mTime;
14266                        if (ass.mNesting > 0) {
14267                            dur += now - ass.mStartTime;
14268                        }
14269                        TimeUtils.formatDuration(dur, pw);
14270                        pw.print(" (");
14271                        pw.print(ass.mCount);
14272                        pw.print(" times)");
14273                        pw.print("  ");
14274                        for (int i=0; i<ass.mStateTimes.length; i++) {
14275                            long amt = ass.mStateTimes[i];
14276                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14277                                amt += now - ass.mLastStateUptime;
14278                            }
14279                            if (amt != 0) {
14280                                pw.print(" ");
14281                                pw.print(ProcessList.makeProcStateString(
14282                                            i + ActivityManager.MIN_PROCESS_STATE));
14283                                pw.print("=");
14284                                TimeUtils.formatDuration(amt, pw);
14285                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14286                                    pw.print("*");
14287                                }
14288                            }
14289                        }
14290                        pw.println();
14291                        if (ass.mNesting > 0) {
14292                            pw.print("    Currently active: ");
14293                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14294                            pw.println();
14295                        }
14296                    }
14297                }
14298            }
14299
14300        }
14301
14302        if (!printedAnything) {
14303            pw.println("  (nothing)");
14304        }
14305    }
14306
14307    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14308            String header, boolean needSep) {
14309        boolean printed = false;
14310        int whichAppId = -1;
14311        if (dumpPackage != null) {
14312            try {
14313                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14314                        dumpPackage, 0);
14315                whichAppId = UserHandle.getAppId(info.uid);
14316            } catch (NameNotFoundException e) {
14317                e.printStackTrace();
14318            }
14319        }
14320        for (int i=0; i<uids.size(); i++) {
14321            UidRecord uidRec = uids.valueAt(i);
14322            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14323                continue;
14324            }
14325            if (!printed) {
14326                printed = true;
14327                if (needSep) {
14328                    pw.println();
14329                }
14330                pw.print("  ");
14331                pw.println(header);
14332                needSep = true;
14333            }
14334            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14335            pw.print(": "); pw.println(uidRec);
14336        }
14337        return printed;
14338    }
14339
14340    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14341            int opti, boolean dumpAll, String dumpPackage) {
14342        boolean needSep = false;
14343        boolean printedAnything = false;
14344        int numPers = 0;
14345
14346        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14347
14348        if (dumpAll) {
14349            final int NP = mProcessNames.getMap().size();
14350            for (int ip=0; ip<NP; ip++) {
14351                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14352                final int NA = procs.size();
14353                for (int ia=0; ia<NA; ia++) {
14354                    ProcessRecord r = procs.valueAt(ia);
14355                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14356                        continue;
14357                    }
14358                    if (!needSep) {
14359                        pw.println("  All known processes:");
14360                        needSep = true;
14361                        printedAnything = true;
14362                    }
14363                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14364                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14365                        pw.print(" "); pw.println(r);
14366                    r.dump(pw, "    ");
14367                    if (r.persistent) {
14368                        numPers++;
14369                    }
14370                }
14371            }
14372        }
14373
14374        if (mIsolatedProcesses.size() > 0) {
14375            boolean printed = false;
14376            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14377                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14378                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14379                    continue;
14380                }
14381                if (!printed) {
14382                    if (needSep) {
14383                        pw.println();
14384                    }
14385                    pw.println("  Isolated process list (sorted by uid):");
14386                    printedAnything = true;
14387                    printed = true;
14388                    needSep = true;
14389                }
14390                pw.println(String.format("%sIsolated #%2d: %s",
14391                        "    ", i, r.toString()));
14392            }
14393        }
14394
14395        if (mActiveUids.size() > 0) {
14396            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14397                printedAnything = needSep = true;
14398            }
14399        }
14400        if (mValidateUids.size() > 0) {
14401            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14402                printedAnything = needSep = true;
14403            }
14404        }
14405
14406        if (mLruProcesses.size() > 0) {
14407            if (needSep) {
14408                pw.println();
14409            }
14410            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14411                    pw.print(" total, non-act at ");
14412                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14413                    pw.print(", non-svc at ");
14414                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14415                    pw.println("):");
14416            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14417            needSep = true;
14418            printedAnything = true;
14419        }
14420
14421        if (dumpAll || dumpPackage != null) {
14422            synchronized (mPidsSelfLocked) {
14423                boolean printed = false;
14424                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14425                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14426                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14427                        continue;
14428                    }
14429                    if (!printed) {
14430                        if (needSep) pw.println();
14431                        needSep = true;
14432                        pw.println("  PID mappings:");
14433                        printed = true;
14434                        printedAnything = true;
14435                    }
14436                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14437                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14438                }
14439            }
14440        }
14441
14442        if (mForegroundProcesses.size() > 0) {
14443            synchronized (mPidsSelfLocked) {
14444                boolean printed = false;
14445                for (int i=0; i<mForegroundProcesses.size(); i++) {
14446                    ProcessRecord r = mPidsSelfLocked.get(
14447                            mForegroundProcesses.valueAt(i).pid);
14448                    if (dumpPackage != null && (r == null
14449                            || !r.pkgList.containsKey(dumpPackage))) {
14450                        continue;
14451                    }
14452                    if (!printed) {
14453                        if (needSep) pw.println();
14454                        needSep = true;
14455                        pw.println("  Foreground Processes:");
14456                        printed = true;
14457                        printedAnything = true;
14458                    }
14459                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14460                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14461                }
14462            }
14463        }
14464
14465        if (mPersistentStartingProcesses.size() > 0) {
14466            if (needSep) pw.println();
14467            needSep = true;
14468            printedAnything = true;
14469            pw.println("  Persisent processes that are starting:");
14470            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14471                    "Starting Norm", "Restarting PERS", dumpPackage);
14472        }
14473
14474        if (mRemovedProcesses.size() > 0) {
14475            if (needSep) pw.println();
14476            needSep = true;
14477            printedAnything = true;
14478            pw.println("  Processes that are being removed:");
14479            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14480                    "Removed Norm", "Removed PERS", dumpPackage);
14481        }
14482
14483        if (mProcessesOnHold.size() > 0) {
14484            if (needSep) pw.println();
14485            needSep = true;
14486            printedAnything = true;
14487            pw.println("  Processes that are on old until the system is ready:");
14488            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14489                    "OnHold Norm", "OnHold PERS", dumpPackage);
14490        }
14491
14492        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14493
14494        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14495        if (needSep) {
14496            printedAnything = true;
14497        }
14498
14499        if (dumpPackage == null) {
14500            pw.println();
14501            needSep = false;
14502            mUserController.dump(pw, dumpAll);
14503        }
14504        if (mHomeProcess != null && (dumpPackage == null
14505                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14506            if (needSep) {
14507                pw.println();
14508                needSep = false;
14509            }
14510            pw.println("  mHomeProcess: " + mHomeProcess);
14511        }
14512        if (mPreviousProcess != null && (dumpPackage == null
14513                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14514            if (needSep) {
14515                pw.println();
14516                needSep = false;
14517            }
14518            pw.println("  mPreviousProcess: " + mPreviousProcess);
14519        }
14520        if (dumpAll) {
14521            StringBuilder sb = new StringBuilder(128);
14522            sb.append("  mPreviousProcessVisibleTime: ");
14523            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14524            pw.println(sb);
14525        }
14526        if (mHeavyWeightProcess != null && (dumpPackage == null
14527                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14528            if (needSep) {
14529                pw.println();
14530                needSep = false;
14531            }
14532            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14533        }
14534        if (dumpPackage == null) {
14535            pw.println("  mConfiguration: " + mConfiguration);
14536        }
14537        if (dumpAll) {
14538            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14539            if (mCompatModePackages.getPackages().size() > 0) {
14540                boolean printed = false;
14541                for (Map.Entry<String, Integer> entry
14542                        : mCompatModePackages.getPackages().entrySet()) {
14543                    String pkg = entry.getKey();
14544                    int mode = entry.getValue();
14545                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14546                        continue;
14547                    }
14548                    if (!printed) {
14549                        pw.println("  mScreenCompatPackages:");
14550                        printed = true;
14551                    }
14552                    pw.print("    "); pw.print(pkg); pw.print(": ");
14553                            pw.print(mode); pw.println();
14554                }
14555            }
14556        }
14557        if (dumpPackage == null) {
14558            pw.println("  mWakefulness="
14559                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14560            pw.println("  mSleepTokens=" + mSleepTokens);
14561            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14562                    + lockScreenShownToString());
14563            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14564            if (mRunningVoice != null) {
14565                pw.println("  mRunningVoice=" + mRunningVoice);
14566                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14567            }
14568        }
14569        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14570                || mOrigWaitForDebugger) {
14571            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14572                    || dumpPackage.equals(mOrigDebugApp)) {
14573                if (needSep) {
14574                    pw.println();
14575                    needSep = false;
14576                }
14577                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14578                        + " mDebugTransient=" + mDebugTransient
14579                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14580            }
14581        }
14582        if (mCurAppTimeTracker != null) {
14583            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14584        }
14585        if (mMemWatchProcesses.getMap().size() > 0) {
14586            pw.println("  Mem watch processes:");
14587            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14588                    = mMemWatchProcesses.getMap();
14589            for (int i=0; i<procs.size(); i++) {
14590                final String proc = procs.keyAt(i);
14591                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14592                for (int j=0; j<uids.size(); j++) {
14593                    if (needSep) {
14594                        pw.println();
14595                        needSep = false;
14596                    }
14597                    StringBuilder sb = new StringBuilder();
14598                    sb.append("    ").append(proc).append('/');
14599                    UserHandle.formatUid(sb, uids.keyAt(j));
14600                    Pair<Long, String> val = uids.valueAt(j);
14601                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14602                    if (val.second != null) {
14603                        sb.append(", report to ").append(val.second);
14604                    }
14605                    pw.println(sb.toString());
14606                }
14607            }
14608            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14609            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14610            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14611                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14612        }
14613        if (mTrackAllocationApp != null) {
14614            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14615                if (needSep) {
14616                    pw.println();
14617                    needSep = false;
14618                }
14619                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14620            }
14621        }
14622        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14623                || mProfileFd != null) {
14624            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14625                if (needSep) {
14626                    pw.println();
14627                    needSep = false;
14628                }
14629                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14630                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14631                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14632                        + mAutoStopProfiler);
14633                pw.println("  mProfileType=" + mProfileType);
14634            }
14635        }
14636        if (mNativeDebuggingApp != null) {
14637            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14638                if (needSep) {
14639                    pw.println();
14640                    needSep = false;
14641                }
14642                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14643            }
14644        }
14645        if (dumpPackage == null) {
14646            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14647                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14648                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14649            }
14650            if (mController != null) {
14651                pw.println("  mController=" + mController
14652                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14653            }
14654            if (dumpAll) {
14655                pw.println("  Total persistent processes: " + numPers);
14656                pw.println("  mProcessesReady=" + mProcessesReady
14657                        + " mSystemReady=" + mSystemReady
14658                        + " mBooted=" + mBooted
14659                        + " mFactoryTest=" + mFactoryTest);
14660                pw.println("  mBooting=" + mBooting
14661                        + " mCallFinishBooting=" + mCallFinishBooting
14662                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14663                pw.print("  mLastPowerCheckRealtime=");
14664                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14665                        pw.println("");
14666                pw.print("  mLastPowerCheckUptime=");
14667                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14668                        pw.println("");
14669                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14670                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14671                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14672                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14673                        + " (" + mLruProcesses.size() + " total)"
14674                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14675                        + " mNumServiceProcs=" + mNumServiceProcs
14676                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14677                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14678                        + " mLastMemoryLevel=" + mLastMemoryLevel
14679                        + " mLastNumProcesses=" + mLastNumProcesses);
14680                long now = SystemClock.uptimeMillis();
14681                pw.print("  mLastIdleTime=");
14682                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14683                        pw.print(" mLowRamSinceLastIdle=");
14684                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14685                        pw.println();
14686            }
14687        }
14688
14689        if (!printedAnything) {
14690            pw.println("  (nothing)");
14691        }
14692    }
14693
14694    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14695            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14696        if (mProcessesToGc.size() > 0) {
14697            boolean printed = false;
14698            long now = SystemClock.uptimeMillis();
14699            for (int i=0; i<mProcessesToGc.size(); i++) {
14700                ProcessRecord proc = mProcessesToGc.get(i);
14701                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14702                    continue;
14703                }
14704                if (!printed) {
14705                    if (needSep) pw.println();
14706                    needSep = true;
14707                    pw.println("  Processes that are waiting to GC:");
14708                    printed = true;
14709                }
14710                pw.print("    Process "); pw.println(proc);
14711                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14712                        pw.print(", last gced=");
14713                        pw.print(now-proc.lastRequestedGc);
14714                        pw.print(" ms ago, last lowMem=");
14715                        pw.print(now-proc.lastLowMemory);
14716                        pw.println(" ms ago");
14717
14718            }
14719        }
14720        return needSep;
14721    }
14722
14723    void printOomLevel(PrintWriter pw, String name, int adj) {
14724        pw.print("    ");
14725        if (adj >= 0) {
14726            pw.print(' ');
14727            if (adj < 10) pw.print(' ');
14728        } else {
14729            if (adj > -10) pw.print(' ');
14730        }
14731        pw.print(adj);
14732        pw.print(": ");
14733        pw.print(name);
14734        pw.print(" (");
14735        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14736        pw.println(")");
14737    }
14738
14739    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14740            int opti, boolean dumpAll) {
14741        boolean needSep = false;
14742
14743        if (mLruProcesses.size() > 0) {
14744            if (needSep) pw.println();
14745            needSep = true;
14746            pw.println("  OOM levels:");
14747            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14748            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14749            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14750            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14751            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14752            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14753            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14754            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14755            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14756            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14757            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14758            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14759            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14760            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14761
14762            if (needSep) pw.println();
14763            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14764                    pw.print(" total, non-act at ");
14765                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14766                    pw.print(", non-svc at ");
14767                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14768                    pw.println("):");
14769            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14770            needSep = true;
14771        }
14772
14773        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14774
14775        pw.println();
14776        pw.println("  mHomeProcess: " + mHomeProcess);
14777        pw.println("  mPreviousProcess: " + mPreviousProcess);
14778        if (mHeavyWeightProcess != null) {
14779            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14780        }
14781
14782        return true;
14783    }
14784
14785    /**
14786     * There are three ways to call this:
14787     *  - no provider specified: dump all the providers
14788     *  - a flattened component name that matched an existing provider was specified as the
14789     *    first arg: dump that one provider
14790     *  - the first arg isn't the flattened component name of an existing provider:
14791     *    dump all providers whose component contains the first arg as a substring
14792     */
14793    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14794            int opti, boolean dumpAll) {
14795        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14796    }
14797
14798    static class ItemMatcher {
14799        ArrayList<ComponentName> components;
14800        ArrayList<String> strings;
14801        ArrayList<Integer> objects;
14802        boolean all;
14803
14804        ItemMatcher() {
14805            all = true;
14806        }
14807
14808        void build(String name) {
14809            ComponentName componentName = ComponentName.unflattenFromString(name);
14810            if (componentName != null) {
14811                if (components == null) {
14812                    components = new ArrayList<ComponentName>();
14813                }
14814                components.add(componentName);
14815                all = false;
14816            } else {
14817                int objectId = 0;
14818                // Not a '/' separated full component name; maybe an object ID?
14819                try {
14820                    objectId = Integer.parseInt(name, 16);
14821                    if (objects == null) {
14822                        objects = new ArrayList<Integer>();
14823                    }
14824                    objects.add(objectId);
14825                    all = false;
14826                } catch (RuntimeException e) {
14827                    // Not an integer; just do string match.
14828                    if (strings == null) {
14829                        strings = new ArrayList<String>();
14830                    }
14831                    strings.add(name);
14832                    all = false;
14833                }
14834            }
14835        }
14836
14837        int build(String[] args, int opti) {
14838            for (; opti<args.length; opti++) {
14839                String name = args[opti];
14840                if ("--".equals(name)) {
14841                    return opti+1;
14842                }
14843                build(name);
14844            }
14845            return opti;
14846        }
14847
14848        boolean match(Object object, ComponentName comp) {
14849            if (all) {
14850                return true;
14851            }
14852            if (components != null) {
14853                for (int i=0; i<components.size(); i++) {
14854                    if (components.get(i).equals(comp)) {
14855                        return true;
14856                    }
14857                }
14858            }
14859            if (objects != null) {
14860                for (int i=0; i<objects.size(); i++) {
14861                    if (System.identityHashCode(object) == objects.get(i)) {
14862                        return true;
14863                    }
14864                }
14865            }
14866            if (strings != null) {
14867                String flat = comp.flattenToString();
14868                for (int i=0; i<strings.size(); i++) {
14869                    if (flat.contains(strings.get(i))) {
14870                        return true;
14871                    }
14872                }
14873            }
14874            return false;
14875        }
14876    }
14877
14878    /**
14879     * There are three things that cmd can be:
14880     *  - a flattened component name that matches an existing activity
14881     *  - the cmd arg isn't the flattened component name of an existing activity:
14882     *    dump all activity whose component contains the cmd as a substring
14883     *  - A hex number of the ActivityRecord object instance.
14884     */
14885    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14886            int opti, boolean dumpAll) {
14887        ArrayList<ActivityRecord> activities;
14888
14889        synchronized (this) {
14890            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14891        }
14892
14893        if (activities.size() <= 0) {
14894            return false;
14895        }
14896
14897        String[] newArgs = new String[args.length - opti];
14898        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14899
14900        TaskRecord lastTask = null;
14901        boolean needSep = false;
14902        for (int i=activities.size()-1; i>=0; i--) {
14903            ActivityRecord r = activities.get(i);
14904            if (needSep) {
14905                pw.println();
14906            }
14907            needSep = true;
14908            synchronized (this) {
14909                if (lastTask != r.task) {
14910                    lastTask = r.task;
14911                    pw.print("TASK "); pw.print(lastTask.affinity);
14912                            pw.print(" id="); pw.println(lastTask.taskId);
14913                    if (dumpAll) {
14914                        lastTask.dump(pw, "  ");
14915                    }
14916                }
14917            }
14918            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14919        }
14920        return true;
14921    }
14922
14923    /**
14924     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14925     * there is a thread associated with the activity.
14926     */
14927    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14928            final ActivityRecord r, String[] args, boolean dumpAll) {
14929        String innerPrefix = prefix + "  ";
14930        synchronized (this) {
14931            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14932                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14933                    pw.print(" pid=");
14934                    if (r.app != null) pw.println(r.app.pid);
14935                    else pw.println("(not running)");
14936            if (dumpAll) {
14937                r.dump(pw, innerPrefix);
14938            }
14939        }
14940        if (r.app != null && r.app.thread != null) {
14941            // flush anything that is already in the PrintWriter since the thread is going
14942            // to write to the file descriptor directly
14943            pw.flush();
14944            try {
14945                TransferPipe tp = new TransferPipe();
14946                try {
14947                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14948                            r.appToken, innerPrefix, args);
14949                    tp.go(fd);
14950                } finally {
14951                    tp.kill();
14952                }
14953            } catch (IOException e) {
14954                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14955            } catch (RemoteException e) {
14956                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14957            }
14958        }
14959    }
14960
14961    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14962            int opti, boolean dumpAll, String dumpPackage) {
14963        boolean needSep = false;
14964        boolean onlyHistory = false;
14965        boolean printedAnything = false;
14966
14967        if ("history".equals(dumpPackage)) {
14968            if (opti < args.length && "-s".equals(args[opti])) {
14969                dumpAll = false;
14970            }
14971            onlyHistory = true;
14972            dumpPackage = null;
14973        }
14974
14975        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14976        if (!onlyHistory && dumpAll) {
14977            if (mRegisteredReceivers.size() > 0) {
14978                boolean printed = false;
14979                Iterator it = mRegisteredReceivers.values().iterator();
14980                while (it.hasNext()) {
14981                    ReceiverList r = (ReceiverList)it.next();
14982                    if (dumpPackage != null && (r.app == null ||
14983                            !dumpPackage.equals(r.app.info.packageName))) {
14984                        continue;
14985                    }
14986                    if (!printed) {
14987                        pw.println("  Registered Receivers:");
14988                        needSep = true;
14989                        printed = true;
14990                        printedAnything = true;
14991                    }
14992                    pw.print("  * "); pw.println(r);
14993                    r.dump(pw, "    ");
14994                }
14995            }
14996
14997            if (mReceiverResolver.dump(pw, needSep ?
14998                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14999                    "    ", dumpPackage, false, false)) {
15000                needSep = true;
15001                printedAnything = true;
15002            }
15003        }
15004
15005        for (BroadcastQueue q : mBroadcastQueues) {
15006            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15007            printedAnything |= needSep;
15008        }
15009
15010        needSep = true;
15011
15012        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15013            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15014                if (needSep) {
15015                    pw.println();
15016                }
15017                needSep = true;
15018                printedAnything = true;
15019                pw.print("  Sticky broadcasts for user ");
15020                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15021                StringBuilder sb = new StringBuilder(128);
15022                for (Map.Entry<String, ArrayList<Intent>> ent
15023                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15024                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15025                    if (dumpAll) {
15026                        pw.println(":");
15027                        ArrayList<Intent> intents = ent.getValue();
15028                        final int N = intents.size();
15029                        for (int i=0; i<N; i++) {
15030                            sb.setLength(0);
15031                            sb.append("    Intent: ");
15032                            intents.get(i).toShortString(sb, false, true, false, false);
15033                            pw.println(sb.toString());
15034                            Bundle bundle = intents.get(i).getExtras();
15035                            if (bundle != null) {
15036                                pw.print("      ");
15037                                pw.println(bundle.toString());
15038                            }
15039                        }
15040                    } else {
15041                        pw.println("");
15042                    }
15043                }
15044            }
15045        }
15046
15047        if (!onlyHistory && dumpAll) {
15048            pw.println();
15049            for (BroadcastQueue queue : mBroadcastQueues) {
15050                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15051                        + queue.mBroadcastsScheduled);
15052            }
15053            pw.println("  mHandler:");
15054            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15055            needSep = true;
15056            printedAnything = true;
15057        }
15058
15059        if (!printedAnything) {
15060            pw.println("  (nothing)");
15061        }
15062    }
15063
15064    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15065            int opti, boolean dumpAll, String dumpPackage) {
15066        if (mCurBroadcastStats == null) {
15067            return;
15068        }
15069
15070        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15071        final long now = SystemClock.elapsedRealtime();
15072        if (mLastBroadcastStats != null) {
15073            pw.print("  Last stats (from ");
15074            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15075            pw.print(" to ");
15076            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15077            pw.print(", ");
15078            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15079                    - mLastBroadcastStats.mStartUptime, pw);
15080            pw.println(" uptime):");
15081            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15082                pw.println("    (nothing)");
15083            }
15084            pw.println();
15085        }
15086        pw.print("  Current stats (from ");
15087        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15088        pw.print(" to now, ");
15089        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15090                - mCurBroadcastStats.mStartUptime, pw);
15091        pw.println(" uptime):");
15092        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15093            pw.println("    (nothing)");
15094        }
15095    }
15096
15097    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15098            int opti, boolean fullCheckin, String dumpPackage) {
15099        if (mCurBroadcastStats == null) {
15100            return;
15101        }
15102
15103        if (mLastBroadcastStats != null) {
15104            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15105            if (fullCheckin) {
15106                mLastBroadcastStats = null;
15107                return;
15108            }
15109        }
15110        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15111        if (fullCheckin) {
15112            mCurBroadcastStats = null;
15113        }
15114    }
15115
15116    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15117            int opti, boolean dumpAll, String dumpPackage) {
15118        boolean needSep;
15119        boolean printedAnything = false;
15120
15121        ItemMatcher matcher = new ItemMatcher();
15122        matcher.build(args, opti);
15123
15124        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15125
15126        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15127        printedAnything |= needSep;
15128
15129        if (mLaunchingProviders.size() > 0) {
15130            boolean printed = false;
15131            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15132                ContentProviderRecord r = mLaunchingProviders.get(i);
15133                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15134                    continue;
15135                }
15136                if (!printed) {
15137                    if (needSep) pw.println();
15138                    needSep = true;
15139                    pw.println("  Launching content providers:");
15140                    printed = true;
15141                    printedAnything = true;
15142                }
15143                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15144                        pw.println(r);
15145            }
15146        }
15147
15148        if (!printedAnything) {
15149            pw.println("  (nothing)");
15150        }
15151    }
15152
15153    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15154            int opti, boolean dumpAll, String dumpPackage) {
15155        boolean needSep = false;
15156        boolean printedAnything = false;
15157
15158        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15159
15160        if (mGrantedUriPermissions.size() > 0) {
15161            boolean printed = false;
15162            int dumpUid = -2;
15163            if (dumpPackage != null) {
15164                try {
15165                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15166                            MATCH_UNINSTALLED_PACKAGES, 0);
15167                } catch (NameNotFoundException e) {
15168                    dumpUid = -1;
15169                }
15170            }
15171            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15172                int uid = mGrantedUriPermissions.keyAt(i);
15173                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15174                    continue;
15175                }
15176                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15177                if (!printed) {
15178                    if (needSep) pw.println();
15179                    needSep = true;
15180                    pw.println("  Granted Uri Permissions:");
15181                    printed = true;
15182                    printedAnything = true;
15183                }
15184                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15185                for (UriPermission perm : perms.values()) {
15186                    pw.print("    "); pw.println(perm);
15187                    if (dumpAll) {
15188                        perm.dump(pw, "      ");
15189                    }
15190                }
15191            }
15192        }
15193
15194        if (!printedAnything) {
15195            pw.println("  (nothing)");
15196        }
15197    }
15198
15199    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15200            int opti, boolean dumpAll, String dumpPackage) {
15201        boolean printed = false;
15202
15203        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15204
15205        if (mIntentSenderRecords.size() > 0) {
15206            Iterator<WeakReference<PendingIntentRecord>> it
15207                    = mIntentSenderRecords.values().iterator();
15208            while (it.hasNext()) {
15209                WeakReference<PendingIntentRecord> ref = it.next();
15210                PendingIntentRecord rec = ref != null ? ref.get(): null;
15211                if (dumpPackage != null && (rec == null
15212                        || !dumpPackage.equals(rec.key.packageName))) {
15213                    continue;
15214                }
15215                printed = true;
15216                if (rec != null) {
15217                    pw.print("  * "); pw.println(rec);
15218                    if (dumpAll) {
15219                        rec.dump(pw, "    ");
15220                    }
15221                } else {
15222                    pw.print("  * "); pw.println(ref);
15223                }
15224            }
15225        }
15226
15227        if (!printed) {
15228            pw.println("  (nothing)");
15229        }
15230    }
15231
15232    private static final int dumpProcessList(PrintWriter pw,
15233            ActivityManagerService service, List list,
15234            String prefix, String normalLabel, String persistentLabel,
15235            String dumpPackage) {
15236        int numPers = 0;
15237        final int N = list.size()-1;
15238        for (int i=N; i>=0; i--) {
15239            ProcessRecord r = (ProcessRecord)list.get(i);
15240            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15241                continue;
15242            }
15243            pw.println(String.format("%s%s #%2d: %s",
15244                    prefix, (r.persistent ? persistentLabel : normalLabel),
15245                    i, r.toString()));
15246            if (r.persistent) {
15247                numPers++;
15248            }
15249        }
15250        return numPers;
15251    }
15252
15253    private static final boolean dumpProcessOomList(PrintWriter pw,
15254            ActivityManagerService service, List<ProcessRecord> origList,
15255            String prefix, String normalLabel, String persistentLabel,
15256            boolean inclDetails, String dumpPackage) {
15257
15258        ArrayList<Pair<ProcessRecord, Integer>> list
15259                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15260        for (int i=0; i<origList.size(); i++) {
15261            ProcessRecord r = origList.get(i);
15262            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15263                continue;
15264            }
15265            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15266        }
15267
15268        if (list.size() <= 0) {
15269            return false;
15270        }
15271
15272        Comparator<Pair<ProcessRecord, Integer>> comparator
15273                = new Comparator<Pair<ProcessRecord, Integer>>() {
15274            @Override
15275            public int compare(Pair<ProcessRecord, Integer> object1,
15276                    Pair<ProcessRecord, Integer> object2) {
15277                if (object1.first.setAdj != object2.first.setAdj) {
15278                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15279                }
15280                if (object1.first.setProcState != object2.first.setProcState) {
15281                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15282                }
15283                if (object1.second.intValue() != object2.second.intValue()) {
15284                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15285                }
15286                return 0;
15287            }
15288        };
15289
15290        Collections.sort(list, comparator);
15291
15292        final long curRealtime = SystemClock.elapsedRealtime();
15293        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15294        final long curUptime = SystemClock.uptimeMillis();
15295        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15296
15297        for (int i=list.size()-1; i>=0; i--) {
15298            ProcessRecord r = list.get(i).first;
15299            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15300            char schedGroup;
15301            switch (r.setSchedGroup) {
15302                case ProcessList.SCHED_GROUP_BACKGROUND:
15303                    schedGroup = 'B';
15304                    break;
15305                case ProcessList.SCHED_GROUP_DEFAULT:
15306                    schedGroup = 'F';
15307                    break;
15308                case ProcessList.SCHED_GROUP_TOP_APP:
15309                    schedGroup = 'T';
15310                    break;
15311                default:
15312                    schedGroup = '?';
15313                    break;
15314            }
15315            char foreground;
15316            if (r.foregroundActivities) {
15317                foreground = 'A';
15318            } else if (r.foregroundServices) {
15319                foreground = 'S';
15320            } else {
15321                foreground = ' ';
15322            }
15323            String procState = ProcessList.makeProcStateString(r.curProcState);
15324            pw.print(prefix);
15325            pw.print(r.persistent ? persistentLabel : normalLabel);
15326            pw.print(" #");
15327            int num = (origList.size()-1)-list.get(i).second;
15328            if (num < 10) pw.print(' ');
15329            pw.print(num);
15330            pw.print(": ");
15331            pw.print(oomAdj);
15332            pw.print(' ');
15333            pw.print(schedGroup);
15334            pw.print('/');
15335            pw.print(foreground);
15336            pw.print('/');
15337            pw.print(procState);
15338            pw.print(" trm:");
15339            if (r.trimMemoryLevel < 10) pw.print(' ');
15340            pw.print(r.trimMemoryLevel);
15341            pw.print(' ');
15342            pw.print(r.toShortString());
15343            pw.print(" (");
15344            pw.print(r.adjType);
15345            pw.println(')');
15346            if (r.adjSource != null || r.adjTarget != null) {
15347                pw.print(prefix);
15348                pw.print("    ");
15349                if (r.adjTarget instanceof ComponentName) {
15350                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15351                } else if (r.adjTarget != null) {
15352                    pw.print(r.adjTarget.toString());
15353                } else {
15354                    pw.print("{null}");
15355                }
15356                pw.print("<=");
15357                if (r.adjSource instanceof ProcessRecord) {
15358                    pw.print("Proc{");
15359                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15360                    pw.println("}");
15361                } else if (r.adjSource != null) {
15362                    pw.println(r.adjSource.toString());
15363                } else {
15364                    pw.println("{null}");
15365                }
15366            }
15367            if (inclDetails) {
15368                pw.print(prefix);
15369                pw.print("    ");
15370                pw.print("oom: max="); pw.print(r.maxAdj);
15371                pw.print(" curRaw="); pw.print(r.curRawAdj);
15372                pw.print(" setRaw="); pw.print(r.setRawAdj);
15373                pw.print(" cur="); pw.print(r.curAdj);
15374                pw.print(" set="); pw.println(r.setAdj);
15375                pw.print(prefix);
15376                pw.print("    ");
15377                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15378                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15379                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15380                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15381                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15382                pw.println();
15383                pw.print(prefix);
15384                pw.print("    ");
15385                pw.print("cached="); pw.print(r.cached);
15386                pw.print(" empty="); pw.print(r.empty);
15387                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15388
15389                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15390                    if (r.lastWakeTime != 0) {
15391                        long wtime;
15392                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15393                        synchronized (stats) {
15394                            wtime = stats.getProcessWakeTime(r.info.uid,
15395                                    r.pid, curRealtime);
15396                        }
15397                        long timeUsed = wtime - r.lastWakeTime;
15398                        pw.print(prefix);
15399                        pw.print("    ");
15400                        pw.print("keep awake over ");
15401                        TimeUtils.formatDuration(realtimeSince, pw);
15402                        pw.print(" used ");
15403                        TimeUtils.formatDuration(timeUsed, pw);
15404                        pw.print(" (");
15405                        pw.print((timeUsed*100)/realtimeSince);
15406                        pw.println("%)");
15407                    }
15408                    if (r.lastCpuTime != 0) {
15409                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15410                        pw.print(prefix);
15411                        pw.print("    ");
15412                        pw.print("run cpu over ");
15413                        TimeUtils.formatDuration(uptimeSince, pw);
15414                        pw.print(" used ");
15415                        TimeUtils.formatDuration(timeUsed, pw);
15416                        pw.print(" (");
15417                        pw.print((timeUsed*100)/uptimeSince);
15418                        pw.println("%)");
15419                    }
15420                }
15421            }
15422        }
15423        return true;
15424    }
15425
15426    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15427            String[] args) {
15428        ArrayList<ProcessRecord> procs;
15429        synchronized (this) {
15430            if (args != null && args.length > start
15431                    && args[start].charAt(0) != '-') {
15432                procs = new ArrayList<ProcessRecord>();
15433                int pid = -1;
15434                try {
15435                    pid = Integer.parseInt(args[start]);
15436                } catch (NumberFormatException e) {
15437                }
15438                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15439                    ProcessRecord proc = mLruProcesses.get(i);
15440                    if (proc.pid == pid) {
15441                        procs.add(proc);
15442                    } else if (allPkgs && proc.pkgList != null
15443                            && proc.pkgList.containsKey(args[start])) {
15444                        procs.add(proc);
15445                    } else if (proc.processName.equals(args[start])) {
15446                        procs.add(proc);
15447                    }
15448                }
15449                if (procs.size() <= 0) {
15450                    return null;
15451                }
15452            } else {
15453                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15454            }
15455        }
15456        return procs;
15457    }
15458
15459    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15460            PrintWriter pw, String[] args) {
15461        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15462        if (procs == null) {
15463            pw.println("No process found for: " + args[0]);
15464            return;
15465        }
15466
15467        long uptime = SystemClock.uptimeMillis();
15468        long realtime = SystemClock.elapsedRealtime();
15469        pw.println("Applications Graphics Acceleration Info:");
15470        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15471
15472        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15473            ProcessRecord r = procs.get(i);
15474            if (r.thread != null) {
15475                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15476                pw.flush();
15477                try {
15478                    TransferPipe tp = new TransferPipe();
15479                    try {
15480                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15481                        tp.go(fd);
15482                    } finally {
15483                        tp.kill();
15484                    }
15485                } catch (IOException e) {
15486                    pw.println("Failure while dumping the app: " + r);
15487                    pw.flush();
15488                } catch (RemoteException e) {
15489                    pw.println("Got a RemoteException while dumping the app " + r);
15490                    pw.flush();
15491                }
15492            }
15493        }
15494    }
15495
15496    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15497        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15498        if (procs == null) {
15499            pw.println("No process found for: " + args[0]);
15500            return;
15501        }
15502
15503        pw.println("Applications Database Info:");
15504
15505        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15506            ProcessRecord r = procs.get(i);
15507            if (r.thread != null) {
15508                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15509                pw.flush();
15510                try {
15511                    TransferPipe tp = new TransferPipe();
15512                    try {
15513                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15514                        tp.go(fd);
15515                    } finally {
15516                        tp.kill();
15517                    }
15518                } catch (IOException e) {
15519                    pw.println("Failure while dumping the app: " + r);
15520                    pw.flush();
15521                } catch (RemoteException e) {
15522                    pw.println("Got a RemoteException while dumping the app " + r);
15523                    pw.flush();
15524                }
15525            }
15526        }
15527    }
15528
15529    final static class MemItem {
15530        final boolean isProc;
15531        final String label;
15532        final String shortLabel;
15533        final long pss;
15534        final long swapPss;
15535        final int id;
15536        final boolean hasActivities;
15537        ArrayList<MemItem> subitems;
15538
15539        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15540                boolean _hasActivities) {
15541            isProc = true;
15542            label = _label;
15543            shortLabel = _shortLabel;
15544            pss = _pss;
15545            swapPss = _swapPss;
15546            id = _id;
15547            hasActivities = _hasActivities;
15548        }
15549
15550        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15551            isProc = false;
15552            label = _label;
15553            shortLabel = _shortLabel;
15554            pss = _pss;
15555            swapPss = _swapPss;
15556            id = _id;
15557            hasActivities = false;
15558        }
15559    }
15560
15561    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15562            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15563        if (sort && !isCompact) {
15564            Collections.sort(items, new Comparator<MemItem>() {
15565                @Override
15566                public int compare(MemItem lhs, MemItem rhs) {
15567                    if (lhs.pss < rhs.pss) {
15568                        return 1;
15569                    } else if (lhs.pss > rhs.pss) {
15570                        return -1;
15571                    }
15572                    return 0;
15573                }
15574            });
15575        }
15576
15577        for (int i=0; i<items.size(); i++) {
15578            MemItem mi = items.get(i);
15579            if (!isCompact) {
15580                if (dumpSwapPss) {
15581                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15582                            mi.label, stringifyKBSize(mi.swapPss));
15583                } else {
15584                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15585                }
15586            } else if (mi.isProc) {
15587                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15588                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15589                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15590                pw.println(mi.hasActivities ? ",a" : ",e");
15591            } else {
15592                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15593                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15594            }
15595            if (mi.subitems != null) {
15596                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15597                        true, isCompact, dumpSwapPss);
15598            }
15599        }
15600    }
15601
15602    // These are in KB.
15603    static final long[] DUMP_MEM_BUCKETS = new long[] {
15604        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15605        120*1024, 160*1024, 200*1024,
15606        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15607        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15608    };
15609
15610    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15611            boolean stackLike) {
15612        int start = label.lastIndexOf('.');
15613        if (start >= 0) start++;
15614        else start = 0;
15615        int end = label.length();
15616        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15617            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15618                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15619                out.append(bucket);
15620                out.append(stackLike ? "MB." : "MB ");
15621                out.append(label, start, end);
15622                return;
15623            }
15624        }
15625        out.append(memKB/1024);
15626        out.append(stackLike ? "MB." : "MB ");
15627        out.append(label, start, end);
15628    }
15629
15630    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15631            ProcessList.NATIVE_ADJ,
15632            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15633            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15634            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15635            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15636            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15637            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15638    };
15639    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15640            "Native",
15641            "System", "Persistent", "Persistent Service", "Foreground",
15642            "Visible", "Perceptible",
15643            "Heavy Weight", "Backup",
15644            "A Services", "Home",
15645            "Previous", "B Services", "Cached"
15646    };
15647    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15648            "native",
15649            "sys", "pers", "persvc", "fore",
15650            "vis", "percept",
15651            "heavy", "backup",
15652            "servicea", "home",
15653            "prev", "serviceb", "cached"
15654    };
15655
15656    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15657            long realtime, boolean isCheckinRequest, boolean isCompact) {
15658        if (isCompact) {
15659            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15660        }
15661        if (isCheckinRequest || isCompact) {
15662            // short checkin version
15663            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15664        } else {
15665            pw.println("Applications Memory Usage (in Kilobytes):");
15666            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15667        }
15668    }
15669
15670    private static final int KSM_SHARED = 0;
15671    private static final int KSM_SHARING = 1;
15672    private static final int KSM_UNSHARED = 2;
15673    private static final int KSM_VOLATILE = 3;
15674
15675    private final long[] getKsmInfo() {
15676        long[] longOut = new long[4];
15677        final int[] SINGLE_LONG_FORMAT = new int[] {
15678            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15679        };
15680        long[] longTmp = new long[1];
15681        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15682                SINGLE_LONG_FORMAT, null, longTmp, null);
15683        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15684        longTmp[0] = 0;
15685        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15686                SINGLE_LONG_FORMAT, null, longTmp, null);
15687        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15688        longTmp[0] = 0;
15689        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15690                SINGLE_LONG_FORMAT, null, longTmp, null);
15691        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15692        longTmp[0] = 0;
15693        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15694                SINGLE_LONG_FORMAT, null, longTmp, null);
15695        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15696        return longOut;
15697    }
15698
15699    private static String stringifySize(long size, int order) {
15700        Locale locale = Locale.US;
15701        switch (order) {
15702            case 1:
15703                return String.format(locale, "%,13d", size);
15704            case 1024:
15705                return String.format(locale, "%,9dK", size / 1024);
15706            case 1024 * 1024:
15707                return String.format(locale, "%,5dM", size / 1024 / 1024);
15708            case 1024 * 1024 * 1024:
15709                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15710            default:
15711                throw new IllegalArgumentException("Invalid size order");
15712        }
15713    }
15714
15715    private static String stringifyKBSize(long size) {
15716        return stringifySize(size * 1024, 1024);
15717    }
15718
15719    // Update this version number in case you change the 'compact' format
15720    private static final int MEMINFO_COMPACT_VERSION = 1;
15721
15722    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15723            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15724        boolean dumpDetails = false;
15725        boolean dumpFullDetails = false;
15726        boolean dumpDalvik = false;
15727        boolean dumpSummaryOnly = false;
15728        boolean dumpUnreachable = false;
15729        boolean oomOnly = false;
15730        boolean isCompact = false;
15731        boolean localOnly = false;
15732        boolean packages = false;
15733        boolean isCheckinRequest = false;
15734        boolean dumpSwapPss = false;
15735
15736        int opti = 0;
15737        while (opti < args.length) {
15738            String opt = args[opti];
15739            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15740                break;
15741            }
15742            opti++;
15743            if ("-a".equals(opt)) {
15744                dumpDetails = true;
15745                dumpFullDetails = true;
15746                dumpDalvik = true;
15747                dumpSwapPss = true;
15748            } else if ("-d".equals(opt)) {
15749                dumpDalvik = true;
15750            } else if ("-c".equals(opt)) {
15751                isCompact = true;
15752            } else if ("-s".equals(opt)) {
15753                dumpDetails = true;
15754                dumpSummaryOnly = true;
15755            } else if ("-S".equals(opt)) {
15756                dumpSwapPss = true;
15757            } else if ("--unreachable".equals(opt)) {
15758                dumpUnreachable = true;
15759            } else if ("--oom".equals(opt)) {
15760                oomOnly = true;
15761            } else if ("--local".equals(opt)) {
15762                localOnly = true;
15763            } else if ("--package".equals(opt)) {
15764                packages = true;
15765            } else if ("--checkin".equals(opt)) {
15766                isCheckinRequest = true;
15767
15768            } else if ("-h".equals(opt)) {
15769                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15770                pw.println("  -a: include all available information for each process.");
15771                pw.println("  -d: include dalvik details.");
15772                pw.println("  -c: dump in a compact machine-parseable representation.");
15773                pw.println("  -s: dump only summary of application memory usage.");
15774                pw.println("  -S: dump also SwapPss.");
15775                pw.println("  --oom: only show processes organized by oom adj.");
15776                pw.println("  --local: only collect details locally, don't call process.");
15777                pw.println("  --package: interpret process arg as package, dumping all");
15778                pw.println("             processes that have loaded that package.");
15779                pw.println("  --checkin: dump data for a checkin");
15780                pw.println("If [process] is specified it can be the name or ");
15781                pw.println("pid of a specific process to dump.");
15782                return;
15783            } else {
15784                pw.println("Unknown argument: " + opt + "; use -h for help");
15785            }
15786        }
15787
15788        long uptime = SystemClock.uptimeMillis();
15789        long realtime = SystemClock.elapsedRealtime();
15790        final long[] tmpLong = new long[1];
15791
15792        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15793        if (procs == null) {
15794            // No Java processes.  Maybe they want to print a native process.
15795            if (args != null && args.length > opti
15796                    && args[opti].charAt(0) != '-') {
15797                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15798                        = new ArrayList<ProcessCpuTracker.Stats>();
15799                updateCpuStatsNow();
15800                int findPid = -1;
15801                try {
15802                    findPid = Integer.parseInt(args[opti]);
15803                } catch (NumberFormatException e) {
15804                }
15805                synchronized (mProcessCpuTracker) {
15806                    final int N = mProcessCpuTracker.countStats();
15807                    for (int i=0; i<N; i++) {
15808                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15809                        if (st.pid == findPid || (st.baseName != null
15810                                && st.baseName.equals(args[opti]))) {
15811                            nativeProcs.add(st);
15812                        }
15813                    }
15814                }
15815                if (nativeProcs.size() > 0) {
15816                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15817                            isCompact);
15818                    Debug.MemoryInfo mi = null;
15819                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15820                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15821                        final int pid = r.pid;
15822                        if (!isCheckinRequest && dumpDetails) {
15823                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15824                        }
15825                        if (mi == null) {
15826                            mi = new Debug.MemoryInfo();
15827                        }
15828                        if (dumpDetails || (!brief && !oomOnly)) {
15829                            Debug.getMemoryInfo(pid, mi);
15830                        } else {
15831                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15832                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15833                        }
15834                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15835                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15836                        if (isCheckinRequest) {
15837                            pw.println();
15838                        }
15839                    }
15840                    return;
15841                }
15842            }
15843            pw.println("No process found for: " + args[opti]);
15844            return;
15845        }
15846
15847        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15848            dumpDetails = true;
15849        }
15850
15851        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15852
15853        String[] innerArgs = new String[args.length-opti];
15854        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15855
15856        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15857        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15858        long nativePss = 0;
15859        long nativeSwapPss = 0;
15860        long dalvikPss = 0;
15861        long dalvikSwapPss = 0;
15862        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15863                EmptyArray.LONG;
15864        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15865                EmptyArray.LONG;
15866        long otherPss = 0;
15867        long otherSwapPss = 0;
15868        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15869        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15870
15871        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15872        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15873        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15874                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15875
15876        long totalPss = 0;
15877        long totalSwapPss = 0;
15878        long cachedPss = 0;
15879        long cachedSwapPss = 0;
15880        boolean hasSwapPss = false;
15881
15882        Debug.MemoryInfo mi = null;
15883        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15884            final ProcessRecord r = procs.get(i);
15885            final IApplicationThread thread;
15886            final int pid;
15887            final int oomAdj;
15888            final boolean hasActivities;
15889            synchronized (this) {
15890                thread = r.thread;
15891                pid = r.pid;
15892                oomAdj = r.getSetAdjWithServices();
15893                hasActivities = r.activities.size() > 0;
15894            }
15895            if (thread != null) {
15896                if (!isCheckinRequest && dumpDetails) {
15897                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15898                }
15899                if (mi == null) {
15900                    mi = new Debug.MemoryInfo();
15901                }
15902                if (dumpDetails || (!brief && !oomOnly)) {
15903                    Debug.getMemoryInfo(pid, mi);
15904                    hasSwapPss = mi.hasSwappedOutPss;
15905                } else {
15906                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15907                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15908                }
15909                if (dumpDetails) {
15910                    if (localOnly) {
15911                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15912                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15913                        if (isCheckinRequest) {
15914                            pw.println();
15915                        }
15916                    } else {
15917                        try {
15918                            pw.flush();
15919                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15920                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15921                        } catch (RemoteException e) {
15922                            if (!isCheckinRequest) {
15923                                pw.println("Got RemoteException!");
15924                                pw.flush();
15925                            }
15926                        }
15927                    }
15928                }
15929
15930                final long myTotalPss = mi.getTotalPss();
15931                final long myTotalUss = mi.getTotalUss();
15932                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15933
15934                synchronized (this) {
15935                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15936                        // Record this for posterity if the process has been stable.
15937                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15938                    }
15939                }
15940
15941                if (!isCheckinRequest && mi != null) {
15942                    totalPss += myTotalPss;
15943                    totalSwapPss += myTotalSwapPss;
15944                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15945                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15946                            myTotalSwapPss, pid, hasActivities);
15947                    procMems.add(pssItem);
15948                    procMemsMap.put(pid, pssItem);
15949
15950                    nativePss += mi.nativePss;
15951                    nativeSwapPss += mi.nativeSwappedOutPss;
15952                    dalvikPss += mi.dalvikPss;
15953                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15954                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15955                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15956                        dalvikSubitemSwapPss[j] +=
15957                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15958                    }
15959                    otherPss += mi.otherPss;
15960                    otherSwapPss += mi.otherSwappedOutPss;
15961                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15962                        long mem = mi.getOtherPss(j);
15963                        miscPss[j] += mem;
15964                        otherPss -= mem;
15965                        mem = mi.getOtherSwappedOutPss(j);
15966                        miscSwapPss[j] += mem;
15967                        otherSwapPss -= mem;
15968                    }
15969
15970                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15971                        cachedPss += myTotalPss;
15972                        cachedSwapPss += myTotalSwapPss;
15973                    }
15974
15975                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15976                        if (oomIndex == (oomPss.length - 1)
15977                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15978                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15979                            oomPss[oomIndex] += myTotalPss;
15980                            oomSwapPss[oomIndex] += myTotalSwapPss;
15981                            if (oomProcs[oomIndex] == null) {
15982                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15983                            }
15984                            oomProcs[oomIndex].add(pssItem);
15985                            break;
15986                        }
15987                    }
15988                }
15989            }
15990        }
15991
15992        long nativeProcTotalPss = 0;
15993
15994        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15995            // If we are showing aggregations, also look for native processes to
15996            // include so that our aggregations are more accurate.
15997            updateCpuStatsNow();
15998            mi = null;
15999            synchronized (mProcessCpuTracker) {
16000                final int N = mProcessCpuTracker.countStats();
16001                for (int i=0; i<N; i++) {
16002                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16003                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16004                        if (mi == null) {
16005                            mi = new Debug.MemoryInfo();
16006                        }
16007                        if (!brief && !oomOnly) {
16008                            Debug.getMemoryInfo(st.pid, mi);
16009                        } else {
16010                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16011                            mi.nativePrivateDirty = (int)tmpLong[0];
16012                        }
16013
16014                        final long myTotalPss = mi.getTotalPss();
16015                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16016                        totalPss += myTotalPss;
16017                        nativeProcTotalPss += myTotalPss;
16018
16019                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16020                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16021                        procMems.add(pssItem);
16022
16023                        nativePss += mi.nativePss;
16024                        nativeSwapPss += mi.nativeSwappedOutPss;
16025                        dalvikPss += mi.dalvikPss;
16026                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16027                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16028                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16029                            dalvikSubitemSwapPss[j] +=
16030                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16031                        }
16032                        otherPss += mi.otherPss;
16033                        otherSwapPss += mi.otherSwappedOutPss;
16034                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16035                            long mem = mi.getOtherPss(j);
16036                            miscPss[j] += mem;
16037                            otherPss -= mem;
16038                            mem = mi.getOtherSwappedOutPss(j);
16039                            miscSwapPss[j] += mem;
16040                            otherSwapPss -= mem;
16041                        }
16042                        oomPss[0] += myTotalPss;
16043                        oomSwapPss[0] += myTotalSwapPss;
16044                        if (oomProcs[0] == null) {
16045                            oomProcs[0] = new ArrayList<MemItem>();
16046                        }
16047                        oomProcs[0].add(pssItem);
16048                    }
16049                }
16050            }
16051
16052            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16053
16054            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16055            final MemItem dalvikItem =
16056                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16057            if (dalvikSubitemPss.length > 0) {
16058                dalvikItem.subitems = new ArrayList<MemItem>();
16059                for (int j=0; j<dalvikSubitemPss.length; j++) {
16060                    final String name = Debug.MemoryInfo.getOtherLabel(
16061                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16062                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16063                                    dalvikSubitemSwapPss[j], j));
16064                }
16065            }
16066            catMems.add(dalvikItem);
16067            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16068            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16069                String label = Debug.MemoryInfo.getOtherLabel(j);
16070                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16071            }
16072
16073            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16074            for (int j=0; j<oomPss.length; j++) {
16075                if (oomPss[j] != 0) {
16076                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16077                            : DUMP_MEM_OOM_LABEL[j];
16078                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16079                            DUMP_MEM_OOM_ADJ[j]);
16080                    item.subitems = oomProcs[j];
16081                    oomMems.add(item);
16082                }
16083            }
16084
16085            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16086            if (!brief && !oomOnly && !isCompact) {
16087                pw.println();
16088                pw.println("Total PSS by process:");
16089                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16090                pw.println();
16091            }
16092            if (!isCompact) {
16093                pw.println("Total PSS by OOM adjustment:");
16094            }
16095            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16096            if (!brief && !oomOnly) {
16097                PrintWriter out = categoryPw != null ? categoryPw : pw;
16098                if (!isCompact) {
16099                    out.println();
16100                    out.println("Total PSS by category:");
16101                }
16102                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16103            }
16104            if (!isCompact) {
16105                pw.println();
16106            }
16107            MemInfoReader memInfo = new MemInfoReader();
16108            memInfo.readMemInfo();
16109            if (nativeProcTotalPss > 0) {
16110                synchronized (this) {
16111                    final long cachedKb = memInfo.getCachedSizeKb();
16112                    final long freeKb = memInfo.getFreeSizeKb();
16113                    final long zramKb = memInfo.getZramTotalSizeKb();
16114                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16115                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16116                            kernelKb*1024, nativeProcTotalPss*1024);
16117                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16118                            nativeProcTotalPss);
16119                }
16120            }
16121            if (!brief) {
16122                if (!isCompact) {
16123                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16124                    pw.print(" (status ");
16125                    switch (mLastMemoryLevel) {
16126                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16127                            pw.println("normal)");
16128                            break;
16129                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16130                            pw.println("moderate)");
16131                            break;
16132                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16133                            pw.println("low)");
16134                            break;
16135                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16136                            pw.println("critical)");
16137                            break;
16138                        default:
16139                            pw.print(mLastMemoryLevel);
16140                            pw.println(")");
16141                            break;
16142                    }
16143                    pw.print(" Free RAM: ");
16144                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16145                            + memInfo.getFreeSizeKb()));
16146                    pw.print(" (");
16147                    pw.print(stringifyKBSize(cachedPss));
16148                    pw.print(" cached pss + ");
16149                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16150                    pw.print(" cached kernel + ");
16151                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16152                    pw.println(" free)");
16153                } else {
16154                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16155                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16156                            + memInfo.getFreeSizeKb()); pw.print(",");
16157                    pw.println(totalPss - cachedPss);
16158                }
16159            }
16160            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16161                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16162                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16163            if (!isCompact) {
16164                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16165                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16166                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16167                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16168                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16169            } else {
16170                pw.print("lostram,"); pw.println(lostRAM);
16171            }
16172            if (!brief) {
16173                if (memInfo.getZramTotalSizeKb() != 0) {
16174                    if (!isCompact) {
16175                        pw.print("     ZRAM: ");
16176                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16177                                pw.print(" physical used for ");
16178                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16179                                        - memInfo.getSwapFreeSizeKb()));
16180                                pw.print(" in swap (");
16181                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16182                                pw.println(" total swap)");
16183                    } else {
16184                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16185                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16186                                pw.println(memInfo.getSwapFreeSizeKb());
16187                    }
16188                }
16189                final long[] ksm = getKsmInfo();
16190                if (!isCompact) {
16191                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16192                            || ksm[KSM_VOLATILE] != 0) {
16193                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16194                                pw.print(" saved from shared ");
16195                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16196                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16197                                pw.print(" unshared; ");
16198                                pw.print(stringifyKBSize(
16199                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16200                    }
16201                    pw.print("   Tuning: ");
16202                    pw.print(ActivityManager.staticGetMemoryClass());
16203                    pw.print(" (large ");
16204                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16205                    pw.print("), oom ");
16206                    pw.print(stringifySize(
16207                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16208                    pw.print(", restore limit ");
16209                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16210                    if (ActivityManager.isLowRamDeviceStatic()) {
16211                        pw.print(" (low-ram)");
16212                    }
16213                    if (ActivityManager.isHighEndGfx()) {
16214                        pw.print(" (high-end-gfx)");
16215                    }
16216                    pw.println();
16217                } else {
16218                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16219                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16220                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16221                    pw.print("tuning,");
16222                    pw.print(ActivityManager.staticGetMemoryClass());
16223                    pw.print(',');
16224                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16225                    pw.print(',');
16226                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16227                    if (ActivityManager.isLowRamDeviceStatic()) {
16228                        pw.print(",low-ram");
16229                    }
16230                    if (ActivityManager.isHighEndGfx()) {
16231                        pw.print(",high-end-gfx");
16232                    }
16233                    pw.println();
16234                }
16235            }
16236        }
16237    }
16238
16239    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16240            long memtrack, String name) {
16241        sb.append("  ");
16242        sb.append(ProcessList.makeOomAdjString(oomAdj));
16243        sb.append(' ');
16244        sb.append(ProcessList.makeProcStateString(procState));
16245        sb.append(' ');
16246        ProcessList.appendRamKb(sb, pss);
16247        sb.append(": ");
16248        sb.append(name);
16249        if (memtrack > 0) {
16250            sb.append(" (");
16251            sb.append(stringifyKBSize(memtrack));
16252            sb.append(" memtrack)");
16253        }
16254    }
16255
16256    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16257        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16258        sb.append(" (pid ");
16259        sb.append(mi.pid);
16260        sb.append(") ");
16261        sb.append(mi.adjType);
16262        sb.append('\n');
16263        if (mi.adjReason != null) {
16264            sb.append("                      ");
16265            sb.append(mi.adjReason);
16266            sb.append('\n');
16267        }
16268    }
16269
16270    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16271        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16272        for (int i=0, N=memInfos.size(); i<N; i++) {
16273            ProcessMemInfo mi = memInfos.get(i);
16274            infoMap.put(mi.pid, mi);
16275        }
16276        updateCpuStatsNow();
16277        long[] memtrackTmp = new long[1];
16278        synchronized (mProcessCpuTracker) {
16279            final int N = mProcessCpuTracker.countStats();
16280            for (int i=0; i<N; i++) {
16281                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16282                if (st.vsize > 0) {
16283                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16284                    if (pss > 0) {
16285                        if (infoMap.indexOfKey(st.pid) < 0) {
16286                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16287                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16288                            mi.pss = pss;
16289                            mi.memtrack = memtrackTmp[0];
16290                            memInfos.add(mi);
16291                        }
16292                    }
16293                }
16294            }
16295        }
16296
16297        long totalPss = 0;
16298        long totalMemtrack = 0;
16299        for (int i=0, N=memInfos.size(); i<N; i++) {
16300            ProcessMemInfo mi = memInfos.get(i);
16301            if (mi.pss == 0) {
16302                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16303                mi.memtrack = memtrackTmp[0];
16304            }
16305            totalPss += mi.pss;
16306            totalMemtrack += mi.memtrack;
16307        }
16308        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16309            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16310                if (lhs.oomAdj != rhs.oomAdj) {
16311                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16312                }
16313                if (lhs.pss != rhs.pss) {
16314                    return lhs.pss < rhs.pss ? 1 : -1;
16315                }
16316                return 0;
16317            }
16318        });
16319
16320        StringBuilder tag = new StringBuilder(128);
16321        StringBuilder stack = new StringBuilder(128);
16322        tag.append("Low on memory -- ");
16323        appendMemBucket(tag, totalPss, "total", false);
16324        appendMemBucket(stack, totalPss, "total", true);
16325
16326        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16327        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16328        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16329
16330        boolean firstLine = true;
16331        int lastOomAdj = Integer.MIN_VALUE;
16332        long extraNativeRam = 0;
16333        long extraNativeMemtrack = 0;
16334        long cachedPss = 0;
16335        for (int i=0, N=memInfos.size(); i<N; i++) {
16336            ProcessMemInfo mi = memInfos.get(i);
16337
16338            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16339                cachedPss += mi.pss;
16340            }
16341
16342            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16343                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16344                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16345                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16346                if (lastOomAdj != mi.oomAdj) {
16347                    lastOomAdj = mi.oomAdj;
16348                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16349                        tag.append(" / ");
16350                    }
16351                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16352                        if (firstLine) {
16353                            stack.append(":");
16354                            firstLine = false;
16355                        }
16356                        stack.append("\n\t at ");
16357                    } else {
16358                        stack.append("$");
16359                    }
16360                } else {
16361                    tag.append(" ");
16362                    stack.append("$");
16363                }
16364                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16365                    appendMemBucket(tag, mi.pss, mi.name, false);
16366                }
16367                appendMemBucket(stack, mi.pss, mi.name, true);
16368                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16369                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16370                    stack.append("(");
16371                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16372                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16373                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16374                            stack.append(":");
16375                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16376                        }
16377                    }
16378                    stack.append(")");
16379                }
16380            }
16381
16382            appendMemInfo(fullNativeBuilder, mi);
16383            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16384                // The short form only has native processes that are >= 512K.
16385                if (mi.pss >= 512) {
16386                    appendMemInfo(shortNativeBuilder, mi);
16387                } else {
16388                    extraNativeRam += mi.pss;
16389                    extraNativeMemtrack += mi.memtrack;
16390                }
16391            } else {
16392                // Short form has all other details, but if we have collected RAM
16393                // from smaller native processes let's dump a summary of that.
16394                if (extraNativeRam > 0) {
16395                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16396                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16397                    shortNativeBuilder.append('\n');
16398                    extraNativeRam = 0;
16399                }
16400                appendMemInfo(fullJavaBuilder, mi);
16401            }
16402        }
16403
16404        fullJavaBuilder.append("           ");
16405        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16406        fullJavaBuilder.append(": TOTAL");
16407        if (totalMemtrack > 0) {
16408            fullJavaBuilder.append(" (");
16409            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16410            fullJavaBuilder.append(" memtrack)");
16411        } else {
16412        }
16413        fullJavaBuilder.append("\n");
16414
16415        MemInfoReader memInfo = new MemInfoReader();
16416        memInfo.readMemInfo();
16417        final long[] infos = memInfo.getRawInfo();
16418
16419        StringBuilder memInfoBuilder = new StringBuilder(1024);
16420        Debug.getMemInfo(infos);
16421        memInfoBuilder.append("  MemInfo: ");
16422        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16423        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16424        memInfoBuilder.append(stringifyKBSize(
16425                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16426        memInfoBuilder.append(stringifyKBSize(
16427                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16428        memInfoBuilder.append(stringifyKBSize(
16429                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16430        memInfoBuilder.append("           ");
16431        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16432        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16433        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16434        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16435        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16436            memInfoBuilder.append("  ZRAM: ");
16437            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16438            memInfoBuilder.append(" RAM, ");
16439            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16440            memInfoBuilder.append(" swap total, ");
16441            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16442            memInfoBuilder.append(" swap free\n");
16443        }
16444        final long[] ksm = getKsmInfo();
16445        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16446                || ksm[KSM_VOLATILE] != 0) {
16447            memInfoBuilder.append("  KSM: ");
16448            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16449            memInfoBuilder.append(" saved from shared ");
16450            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16451            memInfoBuilder.append("\n       ");
16452            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16453            memInfoBuilder.append(" unshared; ");
16454            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16455            memInfoBuilder.append(" volatile\n");
16456        }
16457        memInfoBuilder.append("  Free RAM: ");
16458        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16459                + memInfo.getFreeSizeKb()));
16460        memInfoBuilder.append("\n");
16461        memInfoBuilder.append("  Used RAM: ");
16462        memInfoBuilder.append(stringifyKBSize(
16463                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16464        memInfoBuilder.append("\n");
16465        memInfoBuilder.append("  Lost RAM: ");
16466        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16467                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16468                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16469        memInfoBuilder.append("\n");
16470        Slog.i(TAG, "Low on memory:");
16471        Slog.i(TAG, shortNativeBuilder.toString());
16472        Slog.i(TAG, fullJavaBuilder.toString());
16473        Slog.i(TAG, memInfoBuilder.toString());
16474
16475        StringBuilder dropBuilder = new StringBuilder(1024);
16476        /*
16477        StringWriter oomSw = new StringWriter();
16478        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16479        StringWriter catSw = new StringWriter();
16480        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16481        String[] emptyArgs = new String[] { };
16482        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16483        oomPw.flush();
16484        String oomString = oomSw.toString();
16485        */
16486        dropBuilder.append("Low on memory:");
16487        dropBuilder.append(stack);
16488        dropBuilder.append('\n');
16489        dropBuilder.append(fullNativeBuilder);
16490        dropBuilder.append(fullJavaBuilder);
16491        dropBuilder.append('\n');
16492        dropBuilder.append(memInfoBuilder);
16493        dropBuilder.append('\n');
16494        /*
16495        dropBuilder.append(oomString);
16496        dropBuilder.append('\n');
16497        */
16498        StringWriter catSw = new StringWriter();
16499        synchronized (ActivityManagerService.this) {
16500            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16501            String[] emptyArgs = new String[] { };
16502            catPw.println();
16503            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16504            catPw.println();
16505            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16506                    false, null).dumpLocked();
16507            catPw.println();
16508            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16509            catPw.flush();
16510        }
16511        dropBuilder.append(catSw.toString());
16512        addErrorToDropBox("lowmem", null, "system_server", null,
16513                null, tag.toString(), dropBuilder.toString(), null, null);
16514        //Slog.i(TAG, "Sent to dropbox:");
16515        //Slog.i(TAG, dropBuilder.toString());
16516        synchronized (ActivityManagerService.this) {
16517            long now = SystemClock.uptimeMillis();
16518            if (mLastMemUsageReportTime < now) {
16519                mLastMemUsageReportTime = now;
16520            }
16521        }
16522    }
16523
16524    /**
16525     * Searches array of arguments for the specified string
16526     * @param args array of argument strings
16527     * @param value value to search for
16528     * @return true if the value is contained in the array
16529     */
16530    private static boolean scanArgs(String[] args, String value) {
16531        if (args != null) {
16532            for (String arg : args) {
16533                if (value.equals(arg)) {
16534                    return true;
16535                }
16536            }
16537        }
16538        return false;
16539    }
16540
16541    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16542            ContentProviderRecord cpr, boolean always) {
16543        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16544
16545        if (!inLaunching || always) {
16546            synchronized (cpr) {
16547                cpr.launchingApp = null;
16548                cpr.notifyAll();
16549            }
16550            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16551            String names[] = cpr.info.authority.split(";");
16552            for (int j = 0; j < names.length; j++) {
16553                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16554            }
16555        }
16556
16557        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16558            ContentProviderConnection conn = cpr.connections.get(i);
16559            if (conn.waiting) {
16560                // If this connection is waiting for the provider, then we don't
16561                // need to mess with its process unless we are always removing
16562                // or for some reason the provider is not currently launching.
16563                if (inLaunching && !always) {
16564                    continue;
16565                }
16566            }
16567            ProcessRecord capp = conn.client;
16568            conn.dead = true;
16569            if (conn.stableCount > 0) {
16570                if (!capp.persistent && capp.thread != null
16571                        && capp.pid != 0
16572                        && capp.pid != MY_PID) {
16573                    capp.kill("depends on provider "
16574                            + cpr.name.flattenToShortString()
16575                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16576                }
16577            } else if (capp.thread != null && conn.provider.provider != null) {
16578                try {
16579                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16580                } catch (RemoteException e) {
16581                }
16582                // In the protocol here, we don't expect the client to correctly
16583                // clean up this connection, we'll just remove it.
16584                cpr.connections.remove(i);
16585                if (conn.client.conProviders.remove(conn)) {
16586                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16587                }
16588            }
16589        }
16590
16591        if (inLaunching && always) {
16592            mLaunchingProviders.remove(cpr);
16593        }
16594        return inLaunching;
16595    }
16596
16597    /**
16598     * Main code for cleaning up a process when it has gone away.  This is
16599     * called both as a result of the process dying, or directly when stopping
16600     * a process when running in single process mode.
16601     *
16602     * @return Returns true if the given process has been restarted, so the
16603     * app that was passed in must remain on the process lists.
16604     */
16605    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16606            boolean restarting, boolean allowRestart, int index) {
16607        if (index >= 0) {
16608            removeLruProcessLocked(app);
16609            ProcessList.remove(app.pid);
16610        }
16611
16612        mProcessesToGc.remove(app);
16613        mPendingPssProcesses.remove(app);
16614
16615        // Dismiss any open dialogs.
16616        if (app.crashDialog != null && !app.forceCrashReport) {
16617            app.crashDialog.dismiss();
16618            app.crashDialog = null;
16619        }
16620        if (app.anrDialog != null) {
16621            app.anrDialog.dismiss();
16622            app.anrDialog = null;
16623        }
16624        if (app.waitDialog != null) {
16625            app.waitDialog.dismiss();
16626            app.waitDialog = null;
16627        }
16628
16629        app.crashing = false;
16630        app.notResponding = false;
16631
16632        app.resetPackageList(mProcessStats);
16633        app.unlinkDeathRecipient();
16634        app.makeInactive(mProcessStats);
16635        app.waitingToKill = null;
16636        app.forcingToForeground = null;
16637        updateProcessForegroundLocked(app, false, false);
16638        app.foregroundActivities = false;
16639        app.hasShownUi = false;
16640        app.treatLikeActivity = false;
16641        app.hasAboveClient = false;
16642        app.hasClientActivities = false;
16643
16644        mServices.killServicesLocked(app, allowRestart);
16645
16646        boolean restart = false;
16647
16648        // Remove published content providers.
16649        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16650            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16651            final boolean always = app.bad || !allowRestart;
16652            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16653            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16654                // We left the provider in the launching list, need to
16655                // restart it.
16656                restart = true;
16657            }
16658
16659            cpr.provider = null;
16660            cpr.proc = null;
16661        }
16662        app.pubProviders.clear();
16663
16664        // Take care of any launching providers waiting for this process.
16665        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16666            restart = true;
16667        }
16668
16669        // Unregister from connected content providers.
16670        if (!app.conProviders.isEmpty()) {
16671            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16672                ContentProviderConnection conn = app.conProviders.get(i);
16673                conn.provider.connections.remove(conn);
16674                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16675                        conn.provider.name);
16676            }
16677            app.conProviders.clear();
16678        }
16679
16680        // At this point there may be remaining entries in mLaunchingProviders
16681        // where we were the only one waiting, so they are no longer of use.
16682        // Look for these and clean up if found.
16683        // XXX Commented out for now.  Trying to figure out a way to reproduce
16684        // the actual situation to identify what is actually going on.
16685        if (false) {
16686            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16687                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16688                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16689                    synchronized (cpr) {
16690                        cpr.launchingApp = null;
16691                        cpr.notifyAll();
16692                    }
16693                }
16694            }
16695        }
16696
16697        skipCurrentReceiverLocked(app);
16698
16699        // Unregister any receivers.
16700        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16701            removeReceiverLocked(app.receivers.valueAt(i));
16702        }
16703        app.receivers.clear();
16704
16705        // If the app is undergoing backup, tell the backup manager about it
16706        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16707            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16708                    + mBackupTarget.appInfo + " died during backup");
16709            try {
16710                IBackupManager bm = IBackupManager.Stub.asInterface(
16711                        ServiceManager.getService(Context.BACKUP_SERVICE));
16712                bm.agentDisconnected(app.info.packageName);
16713            } catch (RemoteException e) {
16714                // can't happen; backup manager is local
16715            }
16716        }
16717
16718        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16719            ProcessChangeItem item = mPendingProcessChanges.get(i);
16720            if (item.pid == app.pid) {
16721                mPendingProcessChanges.remove(i);
16722                mAvailProcessChanges.add(item);
16723            }
16724        }
16725        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16726                null).sendToTarget();
16727
16728        // If the caller is restarting this app, then leave it in its
16729        // current lists and let the caller take care of it.
16730        if (restarting) {
16731            return false;
16732        }
16733
16734        if (!app.persistent || app.isolated) {
16735            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16736                    "Removing non-persistent process during cleanup: " + app);
16737            removeProcessNameLocked(app.processName, app.uid);
16738            if (mHeavyWeightProcess == app) {
16739                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16740                        mHeavyWeightProcess.userId, 0));
16741                mHeavyWeightProcess = null;
16742            }
16743        } else if (!app.removed) {
16744            // This app is persistent, so we need to keep its record around.
16745            // If it is not already on the pending app list, add it there
16746            // and start a new process for it.
16747            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16748                mPersistentStartingProcesses.add(app);
16749                restart = true;
16750            }
16751        }
16752        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16753                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16754        mProcessesOnHold.remove(app);
16755
16756        if (app == mHomeProcess) {
16757            mHomeProcess = null;
16758        }
16759        if (app == mPreviousProcess) {
16760            mPreviousProcess = null;
16761        }
16762
16763        if (restart && !app.isolated) {
16764            // We have components that still need to be running in the
16765            // process, so re-launch it.
16766            if (index < 0) {
16767                ProcessList.remove(app.pid);
16768            }
16769            addProcessNameLocked(app);
16770            startProcessLocked(app, "restart", app.processName);
16771            return true;
16772        } else if (app.pid > 0 && app.pid != MY_PID) {
16773            // Goodbye!
16774            boolean removed;
16775            synchronized (mPidsSelfLocked) {
16776                mPidsSelfLocked.remove(app.pid);
16777                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16778            }
16779            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16780            if (app.isolated) {
16781                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16782            }
16783            app.setPid(0);
16784        }
16785        return false;
16786    }
16787
16788    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16789        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16790            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16791            if (cpr.launchingApp == app) {
16792                return true;
16793            }
16794        }
16795        return false;
16796    }
16797
16798    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16799        // Look through the content providers we are waiting to have launched,
16800        // and if any run in this process then either schedule a restart of
16801        // the process or kill the client waiting for it if this process has
16802        // gone bad.
16803        boolean restart = false;
16804        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16805            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16806            if (cpr.launchingApp == app) {
16807                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16808                    restart = true;
16809                } else {
16810                    removeDyingProviderLocked(app, cpr, true);
16811                }
16812            }
16813        }
16814        return restart;
16815    }
16816
16817    // =========================================================
16818    // SERVICES
16819    // =========================================================
16820
16821    @Override
16822    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16823            int flags) {
16824        enforceNotIsolatedCaller("getServices");
16825        synchronized (this) {
16826            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16827        }
16828    }
16829
16830    @Override
16831    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16832        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16833        synchronized (this) {
16834            return mServices.getRunningServiceControlPanelLocked(name);
16835        }
16836    }
16837
16838    @Override
16839    public ComponentName startService(IApplicationThread caller, Intent service,
16840            String resolvedType, String callingPackage, int userId)
16841            throws TransactionTooLargeException {
16842        enforceNotIsolatedCaller("startService");
16843        // Refuse possible leaked file descriptors
16844        if (service != null && service.hasFileDescriptors() == true) {
16845            throw new IllegalArgumentException("File descriptors passed in Intent");
16846        }
16847
16848        if (callingPackage == null) {
16849            throw new IllegalArgumentException("callingPackage cannot be null");
16850        }
16851
16852        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16853                "startService: " + service + " type=" + resolvedType);
16854        synchronized(this) {
16855            final int callingPid = Binder.getCallingPid();
16856            final int callingUid = Binder.getCallingUid();
16857            final long origId = Binder.clearCallingIdentity();
16858            ComponentName res = mServices.startServiceLocked(caller, service,
16859                    resolvedType, callingPid, callingUid, callingPackage, userId);
16860            Binder.restoreCallingIdentity(origId);
16861            return res;
16862        }
16863    }
16864
16865    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16866            String callingPackage, int userId)
16867            throws TransactionTooLargeException {
16868        synchronized(this) {
16869            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16870                    "startServiceInPackage: " + service + " type=" + resolvedType);
16871            final long origId = Binder.clearCallingIdentity();
16872            ComponentName res = mServices.startServiceLocked(null, service,
16873                    resolvedType, -1, uid, callingPackage, userId);
16874            Binder.restoreCallingIdentity(origId);
16875            return res;
16876        }
16877    }
16878
16879    @Override
16880    public int stopService(IApplicationThread caller, Intent service,
16881            String resolvedType, int userId) {
16882        enforceNotIsolatedCaller("stopService");
16883        // Refuse possible leaked file descriptors
16884        if (service != null && service.hasFileDescriptors() == true) {
16885            throw new IllegalArgumentException("File descriptors passed in Intent");
16886        }
16887
16888        synchronized(this) {
16889            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16890        }
16891    }
16892
16893    @Override
16894    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16895        enforceNotIsolatedCaller("peekService");
16896        // Refuse possible leaked file descriptors
16897        if (service != null && service.hasFileDescriptors() == true) {
16898            throw new IllegalArgumentException("File descriptors passed in Intent");
16899        }
16900
16901        if (callingPackage == null) {
16902            throw new IllegalArgumentException("callingPackage cannot be null");
16903        }
16904
16905        synchronized(this) {
16906            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16907        }
16908    }
16909
16910    @Override
16911    public boolean stopServiceToken(ComponentName className, IBinder token,
16912            int startId) {
16913        synchronized(this) {
16914            return mServices.stopServiceTokenLocked(className, token, startId);
16915        }
16916    }
16917
16918    @Override
16919    public void setServiceForeground(ComponentName className, IBinder token,
16920            int id, Notification notification, int flags) {
16921        synchronized(this) {
16922            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16923        }
16924    }
16925
16926    @Override
16927    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16928            boolean requireFull, String name, String callerPackage) {
16929        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16930                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16931    }
16932
16933    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16934            String className, int flags) {
16935        boolean result = false;
16936        // For apps that don't have pre-defined UIDs, check for permission
16937        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16938            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16939                if (ActivityManager.checkUidPermission(
16940                        INTERACT_ACROSS_USERS,
16941                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16942                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16943                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16944                            + " requests FLAG_SINGLE_USER, but app does not hold "
16945                            + INTERACT_ACROSS_USERS;
16946                    Slog.w(TAG, msg);
16947                    throw new SecurityException(msg);
16948                }
16949                // Permission passed
16950                result = true;
16951            }
16952        } else if ("system".equals(componentProcessName)) {
16953            result = true;
16954        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16955            // Phone app and persistent apps are allowed to export singleuser providers.
16956            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16957                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16958        }
16959        if (DEBUG_MU) Slog.v(TAG_MU,
16960                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16961                + Integer.toHexString(flags) + ") = " + result);
16962        return result;
16963    }
16964
16965    /**
16966     * Checks to see if the caller is in the same app as the singleton
16967     * component, or the component is in a special app. It allows special apps
16968     * to export singleton components but prevents exporting singleton
16969     * components for regular apps.
16970     */
16971    boolean isValidSingletonCall(int callingUid, int componentUid) {
16972        int componentAppId = UserHandle.getAppId(componentUid);
16973        return UserHandle.isSameApp(callingUid, componentUid)
16974                || componentAppId == Process.SYSTEM_UID
16975                || componentAppId == Process.PHONE_UID
16976                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16977                        == PackageManager.PERMISSION_GRANTED;
16978    }
16979
16980    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16981            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16982            int userId) throws TransactionTooLargeException {
16983        enforceNotIsolatedCaller("bindService");
16984
16985        // Refuse possible leaked file descriptors
16986        if (service != null && service.hasFileDescriptors() == true) {
16987            throw new IllegalArgumentException("File descriptors passed in Intent");
16988        }
16989
16990        if (callingPackage == null) {
16991            throw new IllegalArgumentException("callingPackage cannot be null");
16992        }
16993
16994        synchronized(this) {
16995            return mServices.bindServiceLocked(caller, token, service,
16996                    resolvedType, connection, flags, callingPackage, userId);
16997        }
16998    }
16999
17000    public boolean unbindService(IServiceConnection connection) {
17001        synchronized (this) {
17002            return mServices.unbindServiceLocked(connection);
17003        }
17004    }
17005
17006    public void publishService(IBinder token, Intent intent, IBinder service) {
17007        // Refuse possible leaked file descriptors
17008        if (intent != null && intent.hasFileDescriptors() == true) {
17009            throw new IllegalArgumentException("File descriptors passed in Intent");
17010        }
17011
17012        synchronized(this) {
17013            if (!(token instanceof ServiceRecord)) {
17014                throw new IllegalArgumentException("Invalid service token");
17015            }
17016            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17017        }
17018    }
17019
17020    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17021        // Refuse possible leaked file descriptors
17022        if (intent != null && intent.hasFileDescriptors() == true) {
17023            throw new IllegalArgumentException("File descriptors passed in Intent");
17024        }
17025
17026        synchronized(this) {
17027            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17028        }
17029    }
17030
17031    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17032        synchronized(this) {
17033            if (!(token instanceof ServiceRecord)) {
17034                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17035                throw new IllegalArgumentException("Invalid service token");
17036            }
17037            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17038        }
17039    }
17040
17041    // =========================================================
17042    // BACKUP AND RESTORE
17043    // =========================================================
17044
17045    // Cause the target app to be launched if necessary and its backup agent
17046    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17047    // activity manager to announce its creation.
17048    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17049        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17050        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17051
17052        IPackageManager pm = AppGlobals.getPackageManager();
17053        ApplicationInfo app = null;
17054        try {
17055            app = pm.getApplicationInfo(packageName, 0, userId);
17056        } catch (RemoteException e) {
17057            // can't happen; package manager is process-local
17058        }
17059        if (app == null) {
17060            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17061            return false;
17062        }
17063
17064        synchronized(this) {
17065            // !!! TODO: currently no check here that we're already bound
17066            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17067            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17068            synchronized (stats) {
17069                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17070            }
17071
17072            // Backup agent is now in use, its package can't be stopped.
17073            try {
17074                AppGlobals.getPackageManager().setPackageStoppedState(
17075                        app.packageName, false, UserHandle.getUserId(app.uid));
17076            } catch (RemoteException e) {
17077            } catch (IllegalArgumentException e) {
17078                Slog.w(TAG, "Failed trying to unstop package "
17079                        + app.packageName + ": " + e);
17080            }
17081
17082            BackupRecord r = new BackupRecord(ss, app, backupMode);
17083            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17084                    ? new ComponentName(app.packageName, app.backupAgentName)
17085                    : new ComponentName("android", "FullBackupAgent");
17086            // startProcessLocked() returns existing proc's record if it's already running
17087            ProcessRecord proc = startProcessLocked(app.processName, app,
17088                    false, 0, "backup", hostingName, false, false, false);
17089            if (proc == null) {
17090                Slog.e(TAG, "Unable to start backup agent process " + r);
17091                return false;
17092            }
17093
17094            // If the app is a regular app (uid >= 10000) and not the system server or phone
17095            // process, etc, then mark it as being in full backup so that certain calls to the
17096            // process can be blocked. This is not reset to false anywhere because we kill the
17097            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17098            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17099                proc.inFullBackup = true;
17100            }
17101            r.app = proc;
17102            mBackupTarget = r;
17103            mBackupAppName = app.packageName;
17104
17105            // Try not to kill the process during backup
17106            updateOomAdjLocked(proc);
17107
17108            // If the process is already attached, schedule the creation of the backup agent now.
17109            // If it is not yet live, this will be done when it attaches to the framework.
17110            if (proc.thread != null) {
17111                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17112                try {
17113                    proc.thread.scheduleCreateBackupAgent(app,
17114                            compatibilityInfoForPackageLocked(app), backupMode);
17115                } catch (RemoteException e) {
17116                    // Will time out on the backup manager side
17117                }
17118            } else {
17119                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17120            }
17121            // Invariants: at this point, the target app process exists and the application
17122            // is either already running or in the process of coming up.  mBackupTarget and
17123            // mBackupAppName describe the app, so that when it binds back to the AM we
17124            // know that it's scheduled for a backup-agent operation.
17125        }
17126
17127        return true;
17128    }
17129
17130    @Override
17131    public void clearPendingBackup() {
17132        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17133        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17134
17135        synchronized (this) {
17136            mBackupTarget = null;
17137            mBackupAppName = null;
17138        }
17139    }
17140
17141    // A backup agent has just come up
17142    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17143        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17144                + " = " + agent);
17145
17146        synchronized(this) {
17147            if (!agentPackageName.equals(mBackupAppName)) {
17148                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17149                return;
17150            }
17151        }
17152
17153        long oldIdent = Binder.clearCallingIdentity();
17154        try {
17155            IBackupManager bm = IBackupManager.Stub.asInterface(
17156                    ServiceManager.getService(Context.BACKUP_SERVICE));
17157            bm.agentConnected(agentPackageName, agent);
17158        } catch (RemoteException e) {
17159            // can't happen; the backup manager service is local
17160        } catch (Exception e) {
17161            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17162            e.printStackTrace();
17163        } finally {
17164            Binder.restoreCallingIdentity(oldIdent);
17165        }
17166    }
17167
17168    // done with this agent
17169    public void unbindBackupAgent(ApplicationInfo appInfo) {
17170        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17171        if (appInfo == null) {
17172            Slog.w(TAG, "unbind backup agent for null app");
17173            return;
17174        }
17175
17176        synchronized(this) {
17177            try {
17178                if (mBackupAppName == null) {
17179                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17180                    return;
17181                }
17182
17183                if (!mBackupAppName.equals(appInfo.packageName)) {
17184                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17185                    return;
17186                }
17187
17188                // Not backing this app up any more; reset its OOM adjustment
17189                final ProcessRecord proc = mBackupTarget.app;
17190                updateOomAdjLocked(proc);
17191
17192                // If the app crashed during backup, 'thread' will be null here
17193                if (proc.thread != null) {
17194                    try {
17195                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17196                                compatibilityInfoForPackageLocked(appInfo));
17197                    } catch (Exception e) {
17198                        Slog.e(TAG, "Exception when unbinding backup agent:");
17199                        e.printStackTrace();
17200                    }
17201                }
17202            } finally {
17203                mBackupTarget = null;
17204                mBackupAppName = null;
17205            }
17206        }
17207    }
17208    // =========================================================
17209    // BROADCASTS
17210    // =========================================================
17211
17212    boolean isPendingBroadcastProcessLocked(int pid) {
17213        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17214                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17215    }
17216
17217    void skipPendingBroadcastLocked(int pid) {
17218            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17219            for (BroadcastQueue queue : mBroadcastQueues) {
17220                queue.skipPendingBroadcastLocked(pid);
17221            }
17222    }
17223
17224    // The app just attached; send any pending broadcasts that it should receive
17225    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17226        boolean didSomething = false;
17227        for (BroadcastQueue queue : mBroadcastQueues) {
17228            didSomething |= queue.sendPendingBroadcastsLocked(app);
17229        }
17230        return didSomething;
17231    }
17232
17233    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17234            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17235        enforceNotIsolatedCaller("registerReceiver");
17236        ArrayList<Intent> stickyIntents = null;
17237        ProcessRecord callerApp = null;
17238        int callingUid;
17239        int callingPid;
17240        synchronized(this) {
17241            if (caller != null) {
17242                callerApp = getRecordForAppLocked(caller);
17243                if (callerApp == null) {
17244                    throw new SecurityException(
17245                            "Unable to find app for caller " + caller
17246                            + " (pid=" + Binder.getCallingPid()
17247                            + ") when registering receiver " + receiver);
17248                }
17249                if (callerApp.info.uid != Process.SYSTEM_UID &&
17250                        !callerApp.pkgList.containsKey(callerPackage) &&
17251                        !"android".equals(callerPackage)) {
17252                    throw new SecurityException("Given caller package " + callerPackage
17253                            + " is not running in process " + callerApp);
17254                }
17255                callingUid = callerApp.info.uid;
17256                callingPid = callerApp.pid;
17257            } else {
17258                callerPackage = null;
17259                callingUid = Binder.getCallingUid();
17260                callingPid = Binder.getCallingPid();
17261            }
17262
17263            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17264                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17265
17266            Iterator<String> actions = filter.actionsIterator();
17267            if (actions == null) {
17268                ArrayList<String> noAction = new ArrayList<String>(1);
17269                noAction.add(null);
17270                actions = noAction.iterator();
17271            }
17272
17273            // Collect stickies of users
17274            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17275            while (actions.hasNext()) {
17276                String action = actions.next();
17277                for (int id : userIds) {
17278                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17279                    if (stickies != null) {
17280                        ArrayList<Intent> intents = stickies.get(action);
17281                        if (intents != null) {
17282                            if (stickyIntents == null) {
17283                                stickyIntents = new ArrayList<Intent>();
17284                            }
17285                            stickyIntents.addAll(intents);
17286                        }
17287                    }
17288                }
17289            }
17290        }
17291
17292        ArrayList<Intent> allSticky = null;
17293        if (stickyIntents != null) {
17294            final ContentResolver resolver = mContext.getContentResolver();
17295            // Look for any matching sticky broadcasts...
17296            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17297                Intent intent = stickyIntents.get(i);
17298                // If intent has scheme "content", it will need to acccess
17299                // provider that needs to lock mProviderMap in ActivityThread
17300                // and also it may need to wait application response, so we
17301                // cannot lock ActivityManagerService here.
17302                if (filter.match(resolver, intent, true, TAG) >= 0) {
17303                    if (allSticky == null) {
17304                        allSticky = new ArrayList<Intent>();
17305                    }
17306                    allSticky.add(intent);
17307                }
17308            }
17309        }
17310
17311        // The first sticky in the list is returned directly back to the client.
17312        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17313        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17314        if (receiver == null) {
17315            return sticky;
17316        }
17317
17318        synchronized (this) {
17319            if (callerApp != null && (callerApp.thread == null
17320                    || callerApp.thread.asBinder() != caller.asBinder())) {
17321                // Original caller already died
17322                return null;
17323            }
17324            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17325            if (rl == null) {
17326                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17327                        userId, receiver);
17328                if (rl.app != null) {
17329                    rl.app.receivers.add(rl);
17330                } else {
17331                    try {
17332                        receiver.asBinder().linkToDeath(rl, 0);
17333                    } catch (RemoteException e) {
17334                        return sticky;
17335                    }
17336                    rl.linkedToDeath = true;
17337                }
17338                mRegisteredReceivers.put(receiver.asBinder(), rl);
17339            } else if (rl.uid != callingUid) {
17340                throw new IllegalArgumentException(
17341                        "Receiver requested to register for uid " + callingUid
17342                        + " was previously registered for uid " + rl.uid);
17343            } else if (rl.pid != callingPid) {
17344                throw new IllegalArgumentException(
17345                        "Receiver requested to register for pid " + callingPid
17346                        + " was previously registered for pid " + rl.pid);
17347            } else if (rl.userId != userId) {
17348                throw new IllegalArgumentException(
17349                        "Receiver requested to register for user " + userId
17350                        + " was previously registered for user " + rl.userId);
17351            }
17352            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17353                    permission, callingUid, userId);
17354            rl.add(bf);
17355            if (!bf.debugCheck()) {
17356                Slog.w(TAG, "==> For Dynamic broadcast");
17357            }
17358            mReceiverResolver.addFilter(bf);
17359
17360            // Enqueue broadcasts for all existing stickies that match
17361            // this filter.
17362            if (allSticky != null) {
17363                ArrayList receivers = new ArrayList();
17364                receivers.add(bf);
17365
17366                final int stickyCount = allSticky.size();
17367                for (int i = 0; i < stickyCount; i++) {
17368                    Intent intent = allSticky.get(i);
17369                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17370                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17371                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17372                            null, 0, null, null, false, true, true, -1);
17373                    queue.enqueueParallelBroadcastLocked(r);
17374                    queue.scheduleBroadcastsLocked();
17375                }
17376            }
17377
17378            return sticky;
17379        }
17380    }
17381
17382    public void unregisterReceiver(IIntentReceiver receiver) {
17383        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17384
17385        final long origId = Binder.clearCallingIdentity();
17386        try {
17387            boolean doTrim = false;
17388
17389            synchronized(this) {
17390                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17391                if (rl != null) {
17392                    final BroadcastRecord r = rl.curBroadcast;
17393                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17394                        final boolean doNext = r.queue.finishReceiverLocked(
17395                                r, r.resultCode, r.resultData, r.resultExtras,
17396                                r.resultAbort, false);
17397                        if (doNext) {
17398                            doTrim = true;
17399                            r.queue.processNextBroadcast(false);
17400                        }
17401                    }
17402
17403                    if (rl.app != null) {
17404                        rl.app.receivers.remove(rl);
17405                    }
17406                    removeReceiverLocked(rl);
17407                    if (rl.linkedToDeath) {
17408                        rl.linkedToDeath = false;
17409                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17410                    }
17411                }
17412            }
17413
17414            // If we actually concluded any broadcasts, we might now be able
17415            // to trim the recipients' apps from our working set
17416            if (doTrim) {
17417                trimApplications();
17418                return;
17419            }
17420
17421        } finally {
17422            Binder.restoreCallingIdentity(origId);
17423        }
17424    }
17425
17426    void removeReceiverLocked(ReceiverList rl) {
17427        mRegisteredReceivers.remove(rl.receiver.asBinder());
17428        for (int i = rl.size() - 1; i >= 0; i--) {
17429            mReceiverResolver.removeFilter(rl.get(i));
17430        }
17431    }
17432
17433    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17434        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17435            ProcessRecord r = mLruProcesses.get(i);
17436            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17437                try {
17438                    r.thread.dispatchPackageBroadcast(cmd, packages);
17439                } catch (RemoteException ex) {
17440                }
17441            }
17442        }
17443    }
17444
17445    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17446            int callingUid, int[] users) {
17447        // TODO: come back and remove this assumption to triage all broadcasts
17448        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17449
17450        List<ResolveInfo> receivers = null;
17451        try {
17452            HashSet<ComponentName> singleUserReceivers = null;
17453            boolean scannedFirstReceivers = false;
17454            for (int user : users) {
17455                // Skip users that have Shell restrictions, with exception of always permitted
17456                // Shell broadcasts
17457                if (callingUid == Process.SHELL_UID
17458                        && mUserController.hasUserRestriction(
17459                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17460                        && !isPermittedShellBroadcast(intent)) {
17461                    continue;
17462                }
17463                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17464                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17465                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17466                    // If this is not the system user, we need to check for
17467                    // any receivers that should be filtered out.
17468                    for (int i=0; i<newReceivers.size(); i++) {
17469                        ResolveInfo ri = newReceivers.get(i);
17470                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17471                            newReceivers.remove(i);
17472                            i--;
17473                        }
17474                    }
17475                }
17476                if (newReceivers != null && newReceivers.size() == 0) {
17477                    newReceivers = null;
17478                }
17479                if (receivers == null) {
17480                    receivers = newReceivers;
17481                } else if (newReceivers != null) {
17482                    // We need to concatenate the additional receivers
17483                    // found with what we have do far.  This would be easy,
17484                    // but we also need to de-dup any receivers that are
17485                    // singleUser.
17486                    if (!scannedFirstReceivers) {
17487                        // Collect any single user receivers we had already retrieved.
17488                        scannedFirstReceivers = true;
17489                        for (int i=0; i<receivers.size(); i++) {
17490                            ResolveInfo ri = receivers.get(i);
17491                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17492                                ComponentName cn = new ComponentName(
17493                                        ri.activityInfo.packageName, ri.activityInfo.name);
17494                                if (singleUserReceivers == null) {
17495                                    singleUserReceivers = new HashSet<ComponentName>();
17496                                }
17497                                singleUserReceivers.add(cn);
17498                            }
17499                        }
17500                    }
17501                    // Add the new results to the existing results, tracking
17502                    // and de-dupping single user receivers.
17503                    for (int i=0; i<newReceivers.size(); i++) {
17504                        ResolveInfo ri = newReceivers.get(i);
17505                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17506                            ComponentName cn = new ComponentName(
17507                                    ri.activityInfo.packageName, ri.activityInfo.name);
17508                            if (singleUserReceivers == null) {
17509                                singleUserReceivers = new HashSet<ComponentName>();
17510                            }
17511                            if (!singleUserReceivers.contains(cn)) {
17512                                singleUserReceivers.add(cn);
17513                                receivers.add(ri);
17514                            }
17515                        } else {
17516                            receivers.add(ri);
17517                        }
17518                    }
17519                }
17520            }
17521        } catch (RemoteException ex) {
17522            // pm is in same process, this will never happen.
17523        }
17524        return receivers;
17525    }
17526
17527    private boolean isPermittedShellBroadcast(Intent intent) {
17528        // remote bugreport should always be allowed to be taken
17529        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17530    }
17531
17532    final int broadcastIntentLocked(ProcessRecord callerApp,
17533            String callerPackage, Intent intent, String resolvedType,
17534            IIntentReceiver resultTo, int resultCode, String resultData,
17535            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17536            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17537        intent = new Intent(intent);
17538
17539        // By default broadcasts do not go to stopped apps.
17540        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17541
17542        // If we have not finished booting, don't allow this to launch new processes.
17543        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17544            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17545        }
17546
17547        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17548                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17549                + " ordered=" + ordered + " userid=" + userId);
17550        if ((resultTo != null) && !ordered) {
17551            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17552        }
17553
17554        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17555                ALLOW_NON_FULL, "broadcast", callerPackage);
17556
17557        // Make sure that the user who is receiving this broadcast is running.
17558        // If not, we will just skip it. Make an exception for shutdown broadcasts
17559        // and upgrade steps.
17560
17561        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17562            if ((callingUid != Process.SYSTEM_UID
17563                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17564                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17565                Slog.w(TAG, "Skipping broadcast of " + intent
17566                        + ": user " + userId + " is stopped");
17567                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17568            }
17569        }
17570
17571        BroadcastOptions brOptions = null;
17572        if (bOptions != null) {
17573            brOptions = new BroadcastOptions(bOptions);
17574            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17575                // See if the caller is allowed to do this.  Note we are checking against
17576                // the actual real caller (not whoever provided the operation as say a
17577                // PendingIntent), because that who is actually supplied the arguments.
17578                if (checkComponentPermission(
17579                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17580                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17581                        != PackageManager.PERMISSION_GRANTED) {
17582                    String msg = "Permission Denial: " + intent.getAction()
17583                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17584                            + ", uid=" + callingUid + ")"
17585                            + " requires "
17586                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17587                    Slog.w(TAG, msg);
17588                    throw new SecurityException(msg);
17589                }
17590            }
17591        }
17592
17593        // Verify that protected broadcasts are only being sent by system code,
17594        // and that system code is only sending protected broadcasts.
17595        final String action = intent.getAction();
17596        final boolean isProtectedBroadcast;
17597        try {
17598            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17599        } catch (RemoteException e) {
17600            Slog.w(TAG, "Remote exception", e);
17601            return ActivityManager.BROADCAST_SUCCESS;
17602        }
17603
17604        final boolean isCallerSystem;
17605        switch (UserHandle.getAppId(callingUid)) {
17606            case Process.ROOT_UID:
17607            case Process.SYSTEM_UID:
17608            case Process.PHONE_UID:
17609            case Process.BLUETOOTH_UID:
17610            case Process.NFC_UID:
17611                isCallerSystem = true;
17612                break;
17613            default:
17614                isCallerSystem = (callerApp != null) && callerApp.persistent;
17615                break;
17616        }
17617
17618        if (isCallerSystem) {
17619            if (isProtectedBroadcast
17620                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17621                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17622                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17623                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17624                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17625                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17626                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17627                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17628                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17629                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17630                // Broadcast is either protected, or it's a public action that
17631                // we've relaxed, so it's fine for system internals to send.
17632            } else {
17633                // The vast majority of broadcasts sent from system internals
17634                // should be protected to avoid security holes, so yell loudly
17635                // to ensure we examine these cases.
17636                if (callerApp != null) {
17637                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17638                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17639                            new Throwable());
17640                } else {
17641                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17642                            + " from system uid " + UserHandle.formatUid(callingUid)
17643                            + " pkg " + callerPackage,
17644                            new Throwable());
17645                }
17646            }
17647
17648        } else {
17649            if (isProtectedBroadcast) {
17650                String msg = "Permission Denial: not allowed to send broadcast "
17651                        + action + " from pid="
17652                        + callingPid + ", uid=" + callingUid;
17653                Slog.w(TAG, msg);
17654                throw new SecurityException(msg);
17655
17656            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17657                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17658                // Special case for compatibility: we don't want apps to send this,
17659                // but historically it has not been protected and apps may be using it
17660                // to poke their own app widget.  So, instead of making it protected,
17661                // just limit it to the caller.
17662                if (callerPackage == null) {
17663                    String msg = "Permission Denial: not allowed to send broadcast "
17664                            + action + " from unknown caller.";
17665                    Slog.w(TAG, msg);
17666                    throw new SecurityException(msg);
17667                } else if (intent.getComponent() != null) {
17668                    // They are good enough to send to an explicit component...  verify
17669                    // it is being sent to the calling app.
17670                    if (!intent.getComponent().getPackageName().equals(
17671                            callerPackage)) {
17672                        String msg = "Permission Denial: not allowed to send broadcast "
17673                                + action + " to "
17674                                + intent.getComponent().getPackageName() + " from "
17675                                + callerPackage;
17676                        Slog.w(TAG, msg);
17677                        throw new SecurityException(msg);
17678                    }
17679                } else {
17680                    // Limit broadcast to their own package.
17681                    intent.setPackage(callerPackage);
17682                }
17683            }
17684        }
17685
17686        if (action != null) {
17687            switch (action) {
17688                case Intent.ACTION_UID_REMOVED:
17689                case Intent.ACTION_PACKAGE_REMOVED:
17690                case Intent.ACTION_PACKAGE_CHANGED:
17691                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17692                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17693                case Intent.ACTION_PACKAGES_SUSPENDED:
17694                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17695                    // Handle special intents: if this broadcast is from the package
17696                    // manager about a package being removed, we need to remove all of
17697                    // its activities from the history stack.
17698                    if (checkComponentPermission(
17699                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17700                            callingPid, callingUid, -1, true)
17701                            != PackageManager.PERMISSION_GRANTED) {
17702                        String msg = "Permission Denial: " + intent.getAction()
17703                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17704                                + ", uid=" + callingUid + ")"
17705                                + " requires "
17706                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17707                        Slog.w(TAG, msg);
17708                        throw new SecurityException(msg);
17709                    }
17710                    switch (action) {
17711                        case Intent.ACTION_UID_REMOVED:
17712                            final Bundle intentExtras = intent.getExtras();
17713                            final int uid = intentExtras != null
17714                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17715                            if (uid >= 0) {
17716                                mBatteryStatsService.removeUid(uid);
17717                                mAppOpsService.uidRemoved(uid);
17718                            }
17719                            break;
17720                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17721                            // If resources are unavailable just force stop all those packages
17722                            // and flush the attribute cache as well.
17723                            String list[] =
17724                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17725                            if (list != null && list.length > 0) {
17726                                for (int i = 0; i < list.length; i++) {
17727                                    forceStopPackageLocked(list[i], -1, false, true, true,
17728                                            false, false, userId, "storage unmount");
17729                                }
17730                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17731                                sendPackageBroadcastLocked(
17732                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17733                                        userId);
17734                            }
17735                            break;
17736                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17737                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17738                            break;
17739                        case Intent.ACTION_PACKAGE_REMOVED:
17740                        case Intent.ACTION_PACKAGE_CHANGED:
17741                            Uri data = intent.getData();
17742                            String ssp;
17743                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17744                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17745                                final boolean replacing =
17746                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17747                                final boolean killProcess =
17748                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17749                                final boolean fullUninstall = removed && !replacing;
17750                                if (removed) {
17751                                    if (killProcess) {
17752                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17753                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17754                                                false, true, true, false, fullUninstall, userId,
17755                                                removed ? "pkg removed" : "pkg changed");
17756                                    }
17757                                    final int cmd = killProcess
17758                                            ? IApplicationThread.PACKAGE_REMOVED
17759                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17760                                    sendPackageBroadcastLocked(cmd,
17761                                            new String[] {ssp}, userId);
17762                                    if (fullUninstall) {
17763                                        mAppOpsService.packageRemoved(
17764                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17765
17766                                        // Remove all permissions granted from/to this package
17767                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17768
17769                                        removeTasksByPackageNameLocked(ssp, userId);
17770                                        mBatteryStatsService.notePackageUninstalled(ssp);
17771                                    }
17772                                } else {
17773                                    if (killProcess) {
17774                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17775                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17776                                                userId, ProcessList.INVALID_ADJ,
17777                                                false, true, true, false, "change " + ssp);
17778                                    }
17779                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17780                                            intent.getStringArrayExtra(
17781                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17782                                }
17783                            }
17784                            break;
17785                        case Intent.ACTION_PACKAGES_SUSPENDED:
17786                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17787                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17788                                    intent.getAction());
17789                            final String[] packageNames = intent.getStringArrayExtra(
17790                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17791                            final int userHandle = intent.getIntExtra(
17792                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17793
17794                            synchronized(ActivityManagerService.this) {
17795                                mRecentTasks.onPackagesSuspendedChanged(
17796                                        packageNames, suspended, userHandle);
17797                            }
17798                            break;
17799                    }
17800                    break;
17801                case Intent.ACTION_PACKAGE_REPLACED:
17802                {
17803                    final Uri data = intent.getData();
17804                    final String ssp;
17805                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17806                        final ApplicationInfo aInfo =
17807                                getPackageManagerInternalLocked().getApplicationInfo(
17808                                        ssp,
17809                                        userId);
17810                        if (aInfo == null) {
17811                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17812                                    + " ssp=" + ssp + " data=" + data);
17813                            return ActivityManager.BROADCAST_SUCCESS;
17814                        }
17815                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17816                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17817                                new String[] {ssp}, userId);
17818                    }
17819                    break;
17820                }
17821                case Intent.ACTION_PACKAGE_ADDED:
17822                {
17823                    // Special case for adding a package: by default turn on compatibility mode.
17824                    Uri data = intent.getData();
17825                    String ssp;
17826                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17827                        final boolean replacing =
17828                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17829                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17830
17831                        try {
17832                            ApplicationInfo ai = AppGlobals.getPackageManager().
17833                                    getApplicationInfo(ssp, 0, 0);
17834                            mBatteryStatsService.notePackageInstalled(ssp,
17835                                    ai != null ? ai.versionCode : 0);
17836                        } catch (RemoteException e) {
17837                        }
17838                    }
17839                    break;
17840                }
17841                case Intent.ACTION_TIMEZONE_CHANGED:
17842                    // If this is the time zone changed action, queue up a message that will reset
17843                    // the timezone of all currently running processes. This message will get
17844                    // queued up before the broadcast happens.
17845                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17846                    break;
17847                case Intent.ACTION_TIME_CHANGED:
17848                    // If the user set the time, let all running processes know.
17849                    final int is24Hour =
17850                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17851                                    : 0;
17852                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17853                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17854                    synchronized (stats) {
17855                        stats.noteCurrentTimeChangedLocked();
17856                    }
17857                    break;
17858                case Intent.ACTION_CLEAR_DNS_CACHE:
17859                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17860                    break;
17861                case Proxy.PROXY_CHANGE_ACTION:
17862                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17863                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17864                    break;
17865                case android.hardware.Camera.ACTION_NEW_PICTURE:
17866                case android.hardware.Camera.ACTION_NEW_VIDEO:
17867                    // These broadcasts are no longer allowed by the system, since they can
17868                    // cause significant thrashing at a crictical point (using the camera).
17869                    // Apps should use JobScehduler to monitor for media provider changes.
17870                    Slog.w(TAG, action + " no longer allowed; dropping from "
17871                            + UserHandle.formatUid(callingUid));
17872                    // Lie; we don't want to crash the app.
17873                    return ActivityManager.BROADCAST_SUCCESS;
17874            }
17875        }
17876
17877        // Add to the sticky list if requested.
17878        if (sticky) {
17879            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17880                    callingPid, callingUid)
17881                    != PackageManager.PERMISSION_GRANTED) {
17882                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17883                        + callingPid + ", uid=" + callingUid
17884                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17885                Slog.w(TAG, msg);
17886                throw new SecurityException(msg);
17887            }
17888            if (requiredPermissions != null && requiredPermissions.length > 0) {
17889                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17890                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17891                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17892            }
17893            if (intent.getComponent() != null) {
17894                throw new SecurityException(
17895                        "Sticky broadcasts can't target a specific component");
17896            }
17897            // We use userId directly here, since the "all" target is maintained
17898            // as a separate set of sticky broadcasts.
17899            if (userId != UserHandle.USER_ALL) {
17900                // But first, if this is not a broadcast to all users, then
17901                // make sure it doesn't conflict with an existing broadcast to
17902                // all users.
17903                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17904                        UserHandle.USER_ALL);
17905                if (stickies != null) {
17906                    ArrayList<Intent> list = stickies.get(intent.getAction());
17907                    if (list != null) {
17908                        int N = list.size();
17909                        int i;
17910                        for (i=0; i<N; i++) {
17911                            if (intent.filterEquals(list.get(i))) {
17912                                throw new IllegalArgumentException(
17913                                        "Sticky broadcast " + intent + " for user "
17914                                        + userId + " conflicts with existing global broadcast");
17915                            }
17916                        }
17917                    }
17918                }
17919            }
17920            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17921            if (stickies == null) {
17922                stickies = new ArrayMap<>();
17923                mStickyBroadcasts.put(userId, stickies);
17924            }
17925            ArrayList<Intent> list = stickies.get(intent.getAction());
17926            if (list == null) {
17927                list = new ArrayList<>();
17928                stickies.put(intent.getAction(), list);
17929            }
17930            final int stickiesCount = list.size();
17931            int i;
17932            for (i = 0; i < stickiesCount; i++) {
17933                if (intent.filterEquals(list.get(i))) {
17934                    // This sticky already exists, replace it.
17935                    list.set(i, new Intent(intent));
17936                    break;
17937                }
17938            }
17939            if (i >= stickiesCount) {
17940                list.add(new Intent(intent));
17941            }
17942        }
17943
17944        int[] users;
17945        if (userId == UserHandle.USER_ALL) {
17946            // Caller wants broadcast to go to all started users.
17947            users = mUserController.getStartedUserArrayLocked();
17948        } else {
17949            // Caller wants broadcast to go to one specific user.
17950            users = new int[] {userId};
17951        }
17952
17953        // Figure out who all will receive this broadcast.
17954        List receivers = null;
17955        List<BroadcastFilter> registeredReceivers = null;
17956        // Need to resolve the intent to interested receivers...
17957        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17958                 == 0) {
17959            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17960        }
17961        if (intent.getComponent() == null) {
17962            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17963                // Query one target user at a time, excluding shell-restricted users
17964                for (int i = 0; i < users.length; i++) {
17965                    if (mUserController.hasUserRestriction(
17966                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17967                        continue;
17968                    }
17969                    List<BroadcastFilter> registeredReceiversForUser =
17970                            mReceiverResolver.queryIntent(intent,
17971                                    resolvedType, false, users[i]);
17972                    if (registeredReceivers == null) {
17973                        registeredReceivers = registeredReceiversForUser;
17974                    } else if (registeredReceiversForUser != null) {
17975                        registeredReceivers.addAll(registeredReceiversForUser);
17976                    }
17977                }
17978            } else {
17979                registeredReceivers = mReceiverResolver.queryIntent(intent,
17980                        resolvedType, false, userId);
17981            }
17982        }
17983
17984        final boolean replacePending =
17985                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17986
17987        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17988                + " replacePending=" + replacePending);
17989
17990        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17991        if (!ordered && NR > 0) {
17992            // If we are not serializing this broadcast, then send the
17993            // registered receivers separately so they don't wait for the
17994            // components to be launched.
17995            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17996            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17997                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17998                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17999                    resultExtras, ordered, sticky, false, userId);
18000            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18001            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18002            if (!replaced) {
18003                queue.enqueueParallelBroadcastLocked(r);
18004                queue.scheduleBroadcastsLocked();
18005            }
18006            registeredReceivers = null;
18007            NR = 0;
18008        }
18009
18010        // Merge into one list.
18011        int ir = 0;
18012        if (receivers != null) {
18013            // A special case for PACKAGE_ADDED: do not allow the package
18014            // being added to see this broadcast.  This prevents them from
18015            // using this as a back door to get run as soon as they are
18016            // installed.  Maybe in the future we want to have a special install
18017            // broadcast or such for apps, but we'd like to deliberately make
18018            // this decision.
18019            String skipPackages[] = null;
18020            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18021                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18022                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18023                Uri data = intent.getData();
18024                if (data != null) {
18025                    String pkgName = data.getSchemeSpecificPart();
18026                    if (pkgName != null) {
18027                        skipPackages = new String[] { pkgName };
18028                    }
18029                }
18030            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18031                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18032            }
18033            if (skipPackages != null && (skipPackages.length > 0)) {
18034                for (String skipPackage : skipPackages) {
18035                    if (skipPackage != null) {
18036                        int NT = receivers.size();
18037                        for (int it=0; it<NT; it++) {
18038                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18039                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18040                                receivers.remove(it);
18041                                it--;
18042                                NT--;
18043                            }
18044                        }
18045                    }
18046                }
18047            }
18048
18049            int NT = receivers != null ? receivers.size() : 0;
18050            int it = 0;
18051            ResolveInfo curt = null;
18052            BroadcastFilter curr = null;
18053            while (it < NT && ir < NR) {
18054                if (curt == null) {
18055                    curt = (ResolveInfo)receivers.get(it);
18056                }
18057                if (curr == null) {
18058                    curr = registeredReceivers.get(ir);
18059                }
18060                if (curr.getPriority() >= curt.priority) {
18061                    // Insert this broadcast record into the final list.
18062                    receivers.add(it, curr);
18063                    ir++;
18064                    curr = null;
18065                    it++;
18066                    NT++;
18067                } else {
18068                    // Skip to the next ResolveInfo in the final list.
18069                    it++;
18070                    curt = null;
18071                }
18072            }
18073        }
18074        while (ir < NR) {
18075            if (receivers == null) {
18076                receivers = new ArrayList();
18077            }
18078            receivers.add(registeredReceivers.get(ir));
18079            ir++;
18080        }
18081
18082        if ((receivers != null && receivers.size() > 0)
18083                || resultTo != null) {
18084            BroadcastQueue queue = broadcastQueueForIntent(intent);
18085            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18086                    callerPackage, callingPid, callingUid, resolvedType,
18087                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18088                    resultData, resultExtras, ordered, sticky, false, userId);
18089
18090            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18091                    + ": prev had " + queue.mOrderedBroadcasts.size());
18092            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18093                    "Enqueueing broadcast " + r.intent.getAction());
18094
18095            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18096            if (!replaced) {
18097                queue.enqueueOrderedBroadcastLocked(r);
18098                queue.scheduleBroadcastsLocked();
18099            }
18100        } else {
18101            // There was nobody interested in the broadcast, but we still want to record
18102            // that it happened.
18103            if (intent.getComponent() == null && intent.getPackage() == null
18104                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18105                // This was an implicit broadcast... let's record it for posterity.
18106                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18107            }
18108        }
18109
18110        return ActivityManager.BROADCAST_SUCCESS;
18111    }
18112
18113    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18114            int skipCount, long dispatchTime) {
18115        final long now = SystemClock.elapsedRealtime();
18116        if (mCurBroadcastStats == null ||
18117                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18118            mLastBroadcastStats = mCurBroadcastStats;
18119            if (mLastBroadcastStats != null) {
18120                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18121                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18122            }
18123            mCurBroadcastStats = new BroadcastStats();
18124        }
18125        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18126    }
18127
18128    final Intent verifyBroadcastLocked(Intent intent) {
18129        // Refuse possible leaked file descriptors
18130        if (intent != null && intent.hasFileDescriptors() == true) {
18131            throw new IllegalArgumentException("File descriptors passed in Intent");
18132        }
18133
18134        int flags = intent.getFlags();
18135
18136        if (!mProcessesReady) {
18137            // if the caller really truly claims to know what they're doing, go
18138            // ahead and allow the broadcast without launching any receivers
18139            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18140                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18141            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18142                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18143                        + " before boot completion");
18144                throw new IllegalStateException("Cannot broadcast before boot completed");
18145            }
18146        }
18147
18148        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18149            throw new IllegalArgumentException(
18150                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18151        }
18152
18153        return intent;
18154    }
18155
18156    public final int broadcastIntent(IApplicationThread caller,
18157            Intent intent, String resolvedType, IIntentReceiver resultTo,
18158            int resultCode, String resultData, Bundle resultExtras,
18159            String[] requiredPermissions, int appOp, Bundle bOptions,
18160            boolean serialized, boolean sticky, int userId) {
18161        enforceNotIsolatedCaller("broadcastIntent");
18162        synchronized(this) {
18163            intent = verifyBroadcastLocked(intent);
18164
18165            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18166            final int callingPid = Binder.getCallingPid();
18167            final int callingUid = Binder.getCallingUid();
18168            final long origId = Binder.clearCallingIdentity();
18169            int res = broadcastIntentLocked(callerApp,
18170                    callerApp != null ? callerApp.info.packageName : null,
18171                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18172                    requiredPermissions, appOp, bOptions, serialized, sticky,
18173                    callingPid, callingUid, userId);
18174            Binder.restoreCallingIdentity(origId);
18175            return res;
18176        }
18177    }
18178
18179
18180    int broadcastIntentInPackage(String packageName, int uid,
18181            Intent intent, String resolvedType, IIntentReceiver resultTo,
18182            int resultCode, String resultData, Bundle resultExtras,
18183            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18184            int userId) {
18185        synchronized(this) {
18186            intent = verifyBroadcastLocked(intent);
18187
18188            final long origId = Binder.clearCallingIdentity();
18189            String[] requiredPermissions = requiredPermission == null ? null
18190                    : new String[] {requiredPermission};
18191            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18192                    resultTo, resultCode, resultData, resultExtras,
18193                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18194                    sticky, -1, uid, userId);
18195            Binder.restoreCallingIdentity(origId);
18196            return res;
18197        }
18198    }
18199
18200    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18201        // Refuse possible leaked file descriptors
18202        if (intent != null && intent.hasFileDescriptors() == true) {
18203            throw new IllegalArgumentException("File descriptors passed in Intent");
18204        }
18205
18206        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18207                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18208
18209        synchronized(this) {
18210            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18211                    != PackageManager.PERMISSION_GRANTED) {
18212                String msg = "Permission Denial: unbroadcastIntent() from pid="
18213                        + Binder.getCallingPid()
18214                        + ", uid=" + Binder.getCallingUid()
18215                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18216                Slog.w(TAG, msg);
18217                throw new SecurityException(msg);
18218            }
18219            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18220            if (stickies != null) {
18221                ArrayList<Intent> list = stickies.get(intent.getAction());
18222                if (list != null) {
18223                    int N = list.size();
18224                    int i;
18225                    for (i=0; i<N; i++) {
18226                        if (intent.filterEquals(list.get(i))) {
18227                            list.remove(i);
18228                            break;
18229                        }
18230                    }
18231                    if (list.size() <= 0) {
18232                        stickies.remove(intent.getAction());
18233                    }
18234                }
18235                if (stickies.size() <= 0) {
18236                    mStickyBroadcasts.remove(userId);
18237                }
18238            }
18239        }
18240    }
18241
18242    void backgroundServicesFinishedLocked(int userId) {
18243        for (BroadcastQueue queue : mBroadcastQueues) {
18244            queue.backgroundServicesFinishedLocked(userId);
18245        }
18246    }
18247
18248    public void finishReceiver(IBinder who, int resultCode, String resultData,
18249            Bundle resultExtras, boolean resultAbort, int flags) {
18250        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18251
18252        // Refuse possible leaked file descriptors
18253        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18254            throw new IllegalArgumentException("File descriptors passed in Bundle");
18255        }
18256
18257        final long origId = Binder.clearCallingIdentity();
18258        try {
18259            boolean doNext = false;
18260            BroadcastRecord r;
18261
18262            synchronized(this) {
18263                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18264                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18265                r = queue.getMatchingOrderedReceiver(who);
18266                if (r != null) {
18267                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18268                        resultData, resultExtras, resultAbort, true);
18269                }
18270            }
18271
18272            if (doNext) {
18273                r.queue.processNextBroadcast(false);
18274            }
18275            trimApplications();
18276        } finally {
18277            Binder.restoreCallingIdentity(origId);
18278        }
18279    }
18280
18281    // =========================================================
18282    // INSTRUMENTATION
18283    // =========================================================
18284
18285    public boolean startInstrumentation(ComponentName className,
18286            String profileFile, int flags, Bundle arguments,
18287            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18288            int userId, String abiOverride) {
18289        enforceNotIsolatedCaller("startInstrumentation");
18290        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18291                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18292        // Refuse possible leaked file descriptors
18293        if (arguments != null && arguments.hasFileDescriptors()) {
18294            throw new IllegalArgumentException("File descriptors passed in Bundle");
18295        }
18296
18297        synchronized(this) {
18298            InstrumentationInfo ii = null;
18299            ApplicationInfo ai = null;
18300            try {
18301                ii = mContext.getPackageManager().getInstrumentationInfo(
18302                    className, STOCK_PM_FLAGS);
18303                ai = AppGlobals.getPackageManager().getApplicationInfo(
18304                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18305            } catch (PackageManager.NameNotFoundException e) {
18306            } catch (RemoteException e) {
18307            }
18308            if (ii == null) {
18309                reportStartInstrumentationFailureLocked(watcher, className,
18310                        "Unable to find instrumentation info for: " + className);
18311                return false;
18312            }
18313            if (ai == null) {
18314                reportStartInstrumentationFailureLocked(watcher, className,
18315                        "Unable to find instrumentation target package: " + ii.targetPackage);
18316                return false;
18317            }
18318            if (!ai.hasCode()) {
18319                reportStartInstrumentationFailureLocked(watcher, className,
18320                        "Instrumentation target has no code: " + ii.targetPackage);
18321                return false;
18322            }
18323
18324            int match = mContext.getPackageManager().checkSignatures(
18325                    ii.targetPackage, ii.packageName);
18326            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18327                String msg = "Permission Denial: starting instrumentation "
18328                        + className + " from pid="
18329                        + Binder.getCallingPid()
18330                        + ", uid=" + Binder.getCallingPid()
18331                        + " not allowed because package " + ii.packageName
18332                        + " does not have a signature matching the target "
18333                        + ii.targetPackage;
18334                reportStartInstrumentationFailureLocked(watcher, className, msg);
18335                throw new SecurityException(msg);
18336            }
18337
18338            final long origId = Binder.clearCallingIdentity();
18339            // Instrumentation can kill and relaunch even persistent processes
18340            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18341                    "start instr");
18342            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18343            app.instrumentationClass = className;
18344            app.instrumentationInfo = ai;
18345            app.instrumentationProfileFile = profileFile;
18346            app.instrumentationArguments = arguments;
18347            app.instrumentationWatcher = watcher;
18348            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18349            app.instrumentationResultClass = className;
18350            Binder.restoreCallingIdentity(origId);
18351        }
18352
18353        return true;
18354    }
18355
18356    /**
18357     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18358     * error to the logs, but if somebody is watching, send the report there too.  This enables
18359     * the "am" command to report errors with more information.
18360     *
18361     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18362     * @param cn The component name of the instrumentation.
18363     * @param report The error report.
18364     */
18365    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18366            ComponentName cn, String report) {
18367        Slog.w(TAG, report);
18368        if (watcher != null) {
18369            Bundle results = new Bundle();
18370            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18371            results.putString("Error", report);
18372            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18373        }
18374    }
18375
18376    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18377        if (app.instrumentationWatcher != null) {
18378            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18379                    app.instrumentationClass, resultCode, results);
18380        }
18381
18382        // Can't call out of the system process with a lock held, so post a message.
18383        if (app.instrumentationUiAutomationConnection != null) {
18384            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18385                    app.instrumentationUiAutomationConnection).sendToTarget();
18386        }
18387
18388        app.instrumentationWatcher = null;
18389        app.instrumentationUiAutomationConnection = null;
18390        app.instrumentationClass = null;
18391        app.instrumentationInfo = null;
18392        app.instrumentationProfileFile = null;
18393        app.instrumentationArguments = null;
18394
18395        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18396                "finished inst");
18397    }
18398
18399    public void finishInstrumentation(IApplicationThread target,
18400            int resultCode, Bundle results) {
18401        int userId = UserHandle.getCallingUserId();
18402        // Refuse possible leaked file descriptors
18403        if (results != null && results.hasFileDescriptors()) {
18404            throw new IllegalArgumentException("File descriptors passed in Intent");
18405        }
18406
18407        synchronized(this) {
18408            ProcessRecord app = getRecordForAppLocked(target);
18409            if (app == null) {
18410                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18411                return;
18412            }
18413            final long origId = Binder.clearCallingIdentity();
18414            finishInstrumentationLocked(app, resultCode, results);
18415            Binder.restoreCallingIdentity(origId);
18416        }
18417    }
18418
18419    // =========================================================
18420    // CONFIGURATION
18421    // =========================================================
18422
18423    public ConfigurationInfo getDeviceConfigurationInfo() {
18424        ConfigurationInfo config = new ConfigurationInfo();
18425        synchronized (this) {
18426            config.reqTouchScreen = mConfiguration.touchscreen;
18427            config.reqKeyboardType = mConfiguration.keyboard;
18428            config.reqNavigation = mConfiguration.navigation;
18429            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18430                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18431                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18432            }
18433            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18434                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18435                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18436            }
18437            config.reqGlEsVersion = GL_ES_VERSION;
18438        }
18439        return config;
18440    }
18441
18442    ActivityStack getFocusedStack() {
18443        return mStackSupervisor.getFocusedStack();
18444    }
18445
18446    @Override
18447    public int getFocusedStackId() throws RemoteException {
18448        ActivityStack focusedStack = getFocusedStack();
18449        if (focusedStack != null) {
18450            return focusedStack.getStackId();
18451        }
18452        return -1;
18453    }
18454
18455    public Configuration getConfiguration() {
18456        Configuration ci;
18457        synchronized(this) {
18458            ci = new Configuration(mConfiguration);
18459            ci.userSetLocale = false;
18460        }
18461        return ci;
18462    }
18463
18464    @Override
18465    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18466        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18467        synchronized (this) {
18468            mSuppressResizeConfigChanges = suppress;
18469        }
18470    }
18471
18472    @Override
18473    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18474        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18475        if (fromStackId == HOME_STACK_ID) {
18476            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18477        }
18478        synchronized (this) {
18479            final long origId = Binder.clearCallingIdentity();
18480            try {
18481                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18482            } finally {
18483                Binder.restoreCallingIdentity(origId);
18484            }
18485        }
18486    }
18487
18488    @Override
18489    public void updatePersistentConfiguration(Configuration values) {
18490        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18491                "updateConfiguration()");
18492        enforceWriteSettingsPermission("updateConfiguration()");
18493        if (values == null) {
18494            throw new NullPointerException("Configuration must not be null");
18495        }
18496
18497        int userId = UserHandle.getCallingUserId();
18498
18499        synchronized(this) {
18500            final long origId = Binder.clearCallingIdentity();
18501            updateConfigurationLocked(values, null, false, true, userId);
18502            Binder.restoreCallingIdentity(origId);
18503        }
18504    }
18505
18506    private void updateFontScaleIfNeeded() {
18507        final int currentUserId;
18508        synchronized(this) {
18509            currentUserId = mUserController.getCurrentUserIdLocked();
18510        }
18511        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18512                FONT_SCALE, 1.0f, currentUserId);
18513        if (mConfiguration.fontScale != scaleFactor) {
18514            final Configuration configuration = mWindowManager.computeNewConfiguration();
18515            configuration.fontScale = scaleFactor;
18516            updatePersistentConfiguration(configuration);
18517        }
18518    }
18519
18520    private void enforceWriteSettingsPermission(String func) {
18521        int uid = Binder.getCallingUid();
18522        if (uid == Process.ROOT_UID) {
18523            return;
18524        }
18525
18526        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18527                Settings.getPackageNameForUid(mContext, uid), false)) {
18528            return;
18529        }
18530
18531        String msg = "Permission Denial: " + func + " from pid="
18532                + Binder.getCallingPid()
18533                + ", uid=" + uid
18534                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18535        Slog.w(TAG, msg);
18536        throw new SecurityException(msg);
18537    }
18538
18539    public void updateConfiguration(Configuration values) {
18540        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18541                "updateConfiguration()");
18542
18543        synchronized(this) {
18544            if (values == null && mWindowManager != null) {
18545                // sentinel: fetch the current configuration from the window manager
18546                values = mWindowManager.computeNewConfiguration();
18547            }
18548
18549            if (mWindowManager != null) {
18550                mProcessList.applyDisplaySize(mWindowManager);
18551            }
18552
18553            final long origId = Binder.clearCallingIdentity();
18554            if (values != null) {
18555                Settings.System.clearConfiguration(values);
18556            }
18557            updateConfigurationLocked(values, null, false);
18558            Binder.restoreCallingIdentity(origId);
18559        }
18560    }
18561
18562    void updateUserConfigurationLocked() {
18563        Configuration configuration = new Configuration(mConfiguration);
18564        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18565                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18566        updateConfigurationLocked(configuration, null, false);
18567    }
18568
18569    boolean updateConfigurationLocked(Configuration values,
18570            ActivityRecord starting, boolean initLocale) {
18571        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18572        return updateConfigurationLocked(values, starting, initLocale, false,
18573                UserHandle.USER_NULL);
18574    }
18575
18576    // To cache the list of supported system locales
18577    private String[] mSupportedSystemLocales = null;
18578
18579    /**
18580     * Do either or both things: (1) change the current configuration, and (2)
18581     * make sure the given activity is running with the (now) current
18582     * configuration.  Returns true if the activity has been left running, or
18583     * false if <var>starting</var> is being destroyed to match the new
18584     * configuration.
18585     *
18586     * @param userId is only used when persistent parameter is set to true to persist configuration
18587     *               for that particular user
18588     */
18589    private boolean updateConfigurationLocked(Configuration values,
18590            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18591        int changes = 0;
18592
18593        if (mWindowManager != null) {
18594            mWindowManager.deferSurfaceLayout();
18595        }
18596        if (values != null) {
18597            Configuration newConfig = new Configuration(mConfiguration);
18598            changes = newConfig.updateFrom(values);
18599            if (changes != 0) {
18600                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18601                        "Updating configuration to: " + values);
18602
18603                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18604
18605                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18606                    final LocaleList locales = values.getLocales();
18607                    int bestLocaleIndex = 0;
18608                    if (locales.size() > 1) {
18609                        if (mSupportedSystemLocales == null) {
18610                            mSupportedSystemLocales =
18611                                    Resources.getSystem().getAssets().getLocales();
18612                        }
18613                        bestLocaleIndex = Math.max(0,
18614                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18615                    }
18616                    SystemProperties.set("persist.sys.locale",
18617                            locales.get(bestLocaleIndex).toLanguageTag());
18618                    LocaleList.setDefault(locales, bestLocaleIndex);
18619                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18620                            locales.get(bestLocaleIndex)));
18621                }
18622
18623                mConfigurationSeq++;
18624                if (mConfigurationSeq <= 0) {
18625                    mConfigurationSeq = 1;
18626                }
18627                newConfig.seq = mConfigurationSeq;
18628                mConfiguration = newConfig;
18629                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18630                mUsageStatsService.reportConfigurationChange(newConfig,
18631                        mUserController.getCurrentUserIdLocked());
18632                //mUsageStatsService.noteStartConfig(newConfig);
18633
18634                final Configuration configCopy = new Configuration(mConfiguration);
18635
18636                // TODO: If our config changes, should we auto dismiss any currently
18637                // showing dialogs?
18638                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18639
18640                AttributeCache ac = AttributeCache.instance();
18641                if (ac != null) {
18642                    ac.updateConfiguration(configCopy);
18643                }
18644
18645                // Make sure all resources in our process are updated
18646                // right now, so that anyone who is going to retrieve
18647                // resource values after we return will be sure to get
18648                // the new ones.  This is especially important during
18649                // boot, where the first config change needs to guarantee
18650                // all resources have that config before following boot
18651                // code is executed.
18652                mSystemThread.applyConfigurationToResources(configCopy);
18653
18654                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18655                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18656                    msg.obj = new Configuration(configCopy);
18657                    msg.arg1 = userId;
18658                    mHandler.sendMessage(msg);
18659                }
18660
18661                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18662                if (isDensityChange) {
18663                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18664                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18665                }
18666
18667                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18668                    ProcessRecord app = mLruProcesses.get(i);
18669                    try {
18670                        if (app.thread != null) {
18671                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18672                                    + app.processName + " new config " + mConfiguration);
18673                            app.thread.scheduleConfigurationChanged(configCopy);
18674                        }
18675                    } catch (Exception e) {
18676                    }
18677                }
18678                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18679                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18680                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18681                        | Intent.FLAG_RECEIVER_FOREGROUND);
18682                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18683                        null, AppOpsManager.OP_NONE, null, false, false,
18684                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18685                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18686                    // Tell the shortcut manager that the system locale changed.  It needs to know
18687                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18688                    // we "push" from here, rather than having the service listen to the broadcast.
18689                    final ShortcutServiceInternal shortcutService =
18690                            LocalServices.getService(ShortcutServiceInternal.class);
18691                    if (shortcutService != null) {
18692                        shortcutService.onSystemLocaleChangedNoLock();
18693                    }
18694
18695                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18696                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18697                    if (!mProcessesReady) {
18698                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18699                    }
18700                    broadcastIntentLocked(null, null, intent,
18701                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18702                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18703                }
18704            }
18705            // Update the configuration with WM first and check if any of the stacks need to be
18706            // resized due to the configuration change. If so, resize the stacks now and do any
18707            // relaunches if necessary. This way we don't need to relaunch again below in
18708            // ensureActivityConfigurationLocked().
18709            if (mWindowManager != null) {
18710                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18711                if (resizedStacks != null) {
18712                    for (int stackId : resizedStacks) {
18713                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18714                        mStackSupervisor.resizeStackLocked(
18715                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18716                    }
18717                }
18718            }
18719        }
18720
18721        boolean kept = true;
18722        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18723        // mainStack is null during startup.
18724        if (mainStack != null) {
18725            if (changes != 0 && starting == null) {
18726                // If the configuration changed, and the caller is not already
18727                // in the process of starting an activity, then find the top
18728                // activity to check if its configuration needs to change.
18729                starting = mainStack.topRunningActivityLocked();
18730            }
18731
18732            if (starting != null && starting.state != ActivityState.STOPPED) {
18733                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18734                // And we need to make sure at this point that all other activities
18735                // are made visible with the correct configuration.
18736                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18737                        !PRESERVE_WINDOWS);
18738            }
18739        }
18740        if (mWindowManager != null) {
18741            mWindowManager.continueSurfaceLayout();
18742        }
18743        return kept;
18744    }
18745
18746    /**
18747     * Decide based on the configuration whether we should shouw the ANR,
18748     * crash, etc dialogs.  The idea is that if there is no affordnace to
18749     * press the on-screen buttons, we shouldn't show the dialog.
18750     *
18751     * A thought: SystemUI might also want to get told about this, the Power
18752     * dialog / global actions also might want different behaviors.
18753     */
18754    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18755        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18756                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18757                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18758        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18759                                    == Configuration.UI_MODE_TYPE_CAR);
18760        return inputMethodExists && uiIsNotCarType && !inVrMode;
18761    }
18762
18763    @Override
18764    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18765        synchronized (this) {
18766            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18767            if (srec != null) {
18768                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18769            }
18770        }
18771        return false;
18772    }
18773
18774    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18775            Intent resultData) {
18776
18777        synchronized (this) {
18778            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18779            if (r != null) {
18780                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18781            }
18782            return false;
18783        }
18784    }
18785
18786    public int getLaunchedFromUid(IBinder activityToken) {
18787        ActivityRecord srec;
18788        synchronized (this) {
18789            srec = ActivityRecord.forTokenLocked(activityToken);
18790        }
18791        if (srec == null) {
18792            return -1;
18793        }
18794        return srec.launchedFromUid;
18795    }
18796
18797    public String getLaunchedFromPackage(IBinder activityToken) {
18798        ActivityRecord srec;
18799        synchronized (this) {
18800            srec = ActivityRecord.forTokenLocked(activityToken);
18801        }
18802        if (srec == null) {
18803            return null;
18804        }
18805        return srec.launchedFromPackage;
18806    }
18807
18808    // =========================================================
18809    // LIFETIME MANAGEMENT
18810    // =========================================================
18811
18812    // Returns which broadcast queue the app is the current [or imminent] receiver
18813    // on, or 'null' if the app is not an active broadcast recipient.
18814    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18815        BroadcastRecord r = app.curReceiver;
18816        if (r != null) {
18817            return r.queue;
18818        }
18819
18820        // It's not the current receiver, but it might be starting up to become one
18821        synchronized (this) {
18822            for (BroadcastQueue queue : mBroadcastQueues) {
18823                r = queue.mPendingBroadcast;
18824                if (r != null && r.curApp == app) {
18825                    // found it; report which queue it's in
18826                    return queue;
18827                }
18828            }
18829        }
18830
18831        return null;
18832    }
18833
18834    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18835            int targetUid, ComponentName targetComponent, String targetProcess) {
18836        if (!mTrackingAssociations) {
18837            return null;
18838        }
18839        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18840                = mAssociations.get(targetUid);
18841        if (components == null) {
18842            components = new ArrayMap<>();
18843            mAssociations.put(targetUid, components);
18844        }
18845        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18846        if (sourceUids == null) {
18847            sourceUids = new SparseArray<>();
18848            components.put(targetComponent, sourceUids);
18849        }
18850        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18851        if (sourceProcesses == null) {
18852            sourceProcesses = new ArrayMap<>();
18853            sourceUids.put(sourceUid, sourceProcesses);
18854        }
18855        Association ass = sourceProcesses.get(sourceProcess);
18856        if (ass == null) {
18857            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18858                    targetProcess);
18859            sourceProcesses.put(sourceProcess, ass);
18860        }
18861        ass.mCount++;
18862        ass.mNesting++;
18863        if (ass.mNesting == 1) {
18864            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18865            ass.mLastState = sourceState;
18866        }
18867        return ass;
18868    }
18869
18870    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18871            ComponentName targetComponent) {
18872        if (!mTrackingAssociations) {
18873            return;
18874        }
18875        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18876                = mAssociations.get(targetUid);
18877        if (components == null) {
18878            return;
18879        }
18880        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18881        if (sourceUids == null) {
18882            return;
18883        }
18884        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18885        if (sourceProcesses == null) {
18886            return;
18887        }
18888        Association ass = sourceProcesses.get(sourceProcess);
18889        if (ass == null || ass.mNesting <= 0) {
18890            return;
18891        }
18892        ass.mNesting--;
18893        if (ass.mNesting == 0) {
18894            long uptime = SystemClock.uptimeMillis();
18895            ass.mTime += uptime - ass.mStartTime;
18896            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18897                    += uptime - ass.mLastStateUptime;
18898            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18899        }
18900    }
18901
18902    private void noteUidProcessState(final int uid, final int state) {
18903        mBatteryStatsService.noteUidProcessState(uid, state);
18904        if (mTrackingAssociations) {
18905            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18906                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18907                        = mAssociations.valueAt(i1);
18908                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18909                    SparseArray<ArrayMap<String, Association>> sourceUids
18910                            = targetComponents.valueAt(i2);
18911                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18912                    if (sourceProcesses != null) {
18913                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18914                            Association ass = sourceProcesses.valueAt(i4);
18915                            if (ass.mNesting >= 1) {
18916                                // currently associated
18917                                long uptime = SystemClock.uptimeMillis();
18918                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18919                                        += uptime - ass.mLastStateUptime;
18920                                ass.mLastState = state;
18921                                ass.mLastStateUptime = uptime;
18922                            }
18923                        }
18924                    }
18925                }
18926            }
18927        }
18928    }
18929
18930    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18931            boolean doingAll, long now) {
18932        if (mAdjSeq == app.adjSeq) {
18933            // This adjustment has already been computed.
18934            return app.curRawAdj;
18935        }
18936
18937        if (app.thread == null) {
18938            app.adjSeq = mAdjSeq;
18939            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18940            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18941            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18942        }
18943
18944        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18945        app.adjSource = null;
18946        app.adjTarget = null;
18947        app.empty = false;
18948        app.cached = false;
18949
18950        final int activitiesSize = app.activities.size();
18951
18952        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18953            // The max adjustment doesn't allow this app to be anything
18954            // below foreground, so it is not worth doing work for it.
18955            app.adjType = "fixed";
18956            app.adjSeq = mAdjSeq;
18957            app.curRawAdj = app.maxAdj;
18958            app.foregroundActivities = false;
18959            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18960            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18961            // System processes can do UI, and when they do we want to have
18962            // them trim their memory after the user leaves the UI.  To
18963            // facilitate this, here we need to determine whether or not it
18964            // is currently showing UI.
18965            app.systemNoUi = true;
18966            if (app == TOP_APP) {
18967                app.systemNoUi = false;
18968                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18969                app.adjType = "pers-top-activity";
18970            } else if (activitiesSize > 0) {
18971                for (int j = 0; j < activitiesSize; j++) {
18972                    final ActivityRecord r = app.activities.get(j);
18973                    if (r.visible) {
18974                        app.systemNoUi = false;
18975                    }
18976                }
18977            }
18978            if (!app.systemNoUi) {
18979                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18980            }
18981            return (app.curAdj=app.maxAdj);
18982        }
18983
18984        app.systemNoUi = false;
18985
18986        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18987
18988        // Determine the importance of the process, starting with most
18989        // important to least, and assign an appropriate OOM adjustment.
18990        int adj;
18991        int schedGroup;
18992        int procState;
18993        boolean foregroundActivities = false;
18994        BroadcastQueue queue;
18995        if (app == TOP_APP) {
18996            // The last app on the list is the foreground app.
18997            adj = ProcessList.FOREGROUND_APP_ADJ;
18998            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18999            app.adjType = "top-activity";
19000            foregroundActivities = true;
19001            procState = PROCESS_STATE_CUR_TOP;
19002        } else if (app.instrumentationClass != null) {
19003            // Don't want to kill running instrumentation.
19004            adj = ProcessList.FOREGROUND_APP_ADJ;
19005            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19006            app.adjType = "instrumentation";
19007            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19008        } else if ((queue = isReceivingBroadcast(app)) != null) {
19009            // An app that is currently receiving a broadcast also
19010            // counts as being in the foreground for OOM killer purposes.
19011            // It's placed in a sched group based on the nature of the
19012            // broadcast as reflected by which queue it's active in.
19013            adj = ProcessList.FOREGROUND_APP_ADJ;
19014            schedGroup = (queue == mFgBroadcastQueue)
19015                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19016            app.adjType = "broadcast";
19017            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19018        } else if (app.executingServices.size() > 0) {
19019            // An app that is currently executing a service callback also
19020            // counts as being in the foreground.
19021            adj = ProcessList.FOREGROUND_APP_ADJ;
19022            schedGroup = app.execServicesFg ?
19023                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19024            app.adjType = "exec-service";
19025            procState = ActivityManager.PROCESS_STATE_SERVICE;
19026            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19027        } else {
19028            // As far as we know the process is empty.  We may change our mind later.
19029            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19030            // At this point we don't actually know the adjustment.  Use the cached adj
19031            // value that the caller wants us to.
19032            adj = cachedAdj;
19033            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19034            app.cached = true;
19035            app.empty = true;
19036            app.adjType = "cch-empty";
19037        }
19038
19039        // Examine all activities if not already foreground.
19040        if (!foregroundActivities && activitiesSize > 0) {
19041            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19042            for (int j = 0; j < activitiesSize; j++) {
19043                final ActivityRecord r = app.activities.get(j);
19044                if (r.app != app) {
19045                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19046                            + " instead of expected " + app);
19047                    if (r.app == null || (r.app.uid == app.uid)) {
19048                        // Only fix things up when they look sane
19049                        r.app = app;
19050                    } else {
19051                        continue;
19052                    }
19053                }
19054                if (r.visible) {
19055                    // App has a visible activity; only upgrade adjustment.
19056                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19057                        adj = ProcessList.VISIBLE_APP_ADJ;
19058                        app.adjType = "visible";
19059                    }
19060                    if (procState > PROCESS_STATE_CUR_TOP) {
19061                        procState = PROCESS_STATE_CUR_TOP;
19062                    }
19063                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19064                    app.cached = false;
19065                    app.empty = false;
19066                    foregroundActivities = true;
19067                    if (r.task != null && minLayer > 0) {
19068                        final int layer = r.task.mLayerRank;
19069                        if (layer >= 0 && minLayer > layer) {
19070                            minLayer = layer;
19071                        }
19072                    }
19073                    break;
19074                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19075                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19076                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19077                        app.adjType = "pausing";
19078                    }
19079                    if (procState > PROCESS_STATE_CUR_TOP) {
19080                        procState = PROCESS_STATE_CUR_TOP;
19081                    }
19082                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19083                    app.cached = false;
19084                    app.empty = false;
19085                    foregroundActivities = true;
19086                } else if (r.state == ActivityState.STOPPING) {
19087                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19088                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19089                        app.adjType = "stopping";
19090                    }
19091                    // For the process state, we will at this point consider the
19092                    // process to be cached.  It will be cached either as an activity
19093                    // or empty depending on whether the activity is finishing.  We do
19094                    // this so that we can treat the process as cached for purposes of
19095                    // memory trimming (determing current memory level, trim command to
19096                    // send to process) since there can be an arbitrary number of stopping
19097                    // processes and they should soon all go into the cached state.
19098                    if (!r.finishing) {
19099                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19100                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19101                        }
19102                    }
19103                    app.cached = false;
19104                    app.empty = false;
19105                    foregroundActivities = true;
19106                } else {
19107                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19108                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19109                        app.adjType = "cch-act";
19110                    }
19111                }
19112            }
19113            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19114                adj += minLayer;
19115            }
19116        }
19117
19118        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19119                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19120            if (app.foregroundServices) {
19121                // The user is aware of this app, so make it visible.
19122                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19123                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19124                app.cached = false;
19125                app.adjType = "fg-service";
19126                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19127            } else if (app.forcingToForeground != null) {
19128                // The user is aware of this app, so make it visible.
19129                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19130                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19131                app.cached = false;
19132                app.adjType = "force-fg";
19133                app.adjSource = app.forcingToForeground;
19134                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19135            }
19136        }
19137
19138        if (app == mHeavyWeightProcess) {
19139            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19140                // We don't want to kill the current heavy-weight process.
19141                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19142                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19143                app.cached = false;
19144                app.adjType = "heavy";
19145            }
19146            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19147                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19148            }
19149        }
19150
19151        if (app == mHomeProcess) {
19152            if (adj > ProcessList.HOME_APP_ADJ) {
19153                // This process is hosting what we currently consider to be the
19154                // home app, so we don't want to let it go into the background.
19155                adj = ProcessList.HOME_APP_ADJ;
19156                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19157                app.cached = false;
19158                app.adjType = "home";
19159            }
19160            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19161                procState = ActivityManager.PROCESS_STATE_HOME;
19162            }
19163        }
19164
19165        if (app == mPreviousProcess && app.activities.size() > 0) {
19166            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19167                // This was the previous process that showed UI to the user.
19168                // We want to try to keep it around more aggressively, to give
19169                // a good experience around switching between two apps.
19170                adj = ProcessList.PREVIOUS_APP_ADJ;
19171                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19172                app.cached = false;
19173                app.adjType = "previous";
19174            }
19175            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19176                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19177            }
19178        }
19179
19180        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19181                + " reason=" + app.adjType);
19182
19183        // By default, we use the computed adjustment.  It may be changed if
19184        // there are applications dependent on our services or providers, but
19185        // this gives us a baseline and makes sure we don't get into an
19186        // infinite recursion.
19187        app.adjSeq = mAdjSeq;
19188        app.curRawAdj = adj;
19189        app.hasStartedServices = false;
19190
19191        if (mBackupTarget != null && app == mBackupTarget.app) {
19192            // If possible we want to avoid killing apps while they're being backed up
19193            if (adj > ProcessList.BACKUP_APP_ADJ) {
19194                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19195                adj = ProcessList.BACKUP_APP_ADJ;
19196                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19197                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19198                }
19199                app.adjType = "backup";
19200                app.cached = false;
19201            }
19202            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19203                procState = ActivityManager.PROCESS_STATE_BACKUP;
19204            }
19205        }
19206
19207        boolean mayBeTop = false;
19208
19209        for (int is = app.services.size()-1;
19210                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19211                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19212                        || procState > ActivityManager.PROCESS_STATE_TOP);
19213                is--) {
19214            ServiceRecord s = app.services.valueAt(is);
19215            if (s.startRequested) {
19216                app.hasStartedServices = true;
19217                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19218                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19219                }
19220                if (app.hasShownUi && app != mHomeProcess) {
19221                    // If this process has shown some UI, let it immediately
19222                    // go to the LRU list because it may be pretty heavy with
19223                    // UI stuff.  We'll tag it with a label just to help
19224                    // debug and understand what is going on.
19225                    if (adj > ProcessList.SERVICE_ADJ) {
19226                        app.adjType = "cch-started-ui-services";
19227                    }
19228                } else {
19229                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19230                        // This service has seen some activity within
19231                        // recent memory, so we will keep its process ahead
19232                        // of the background processes.
19233                        if (adj > ProcessList.SERVICE_ADJ) {
19234                            adj = ProcessList.SERVICE_ADJ;
19235                            app.adjType = "started-services";
19236                            app.cached = false;
19237                        }
19238                    }
19239                    // If we have let the service slide into the background
19240                    // state, still have some text describing what it is doing
19241                    // even though the service no longer has an impact.
19242                    if (adj > ProcessList.SERVICE_ADJ) {
19243                        app.adjType = "cch-started-services";
19244                    }
19245                }
19246            }
19247
19248            app.whitelistManager = false;
19249
19250            for (int conni = s.connections.size()-1;
19251                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19252                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19253                            || procState > ActivityManager.PROCESS_STATE_TOP);
19254                    conni--) {
19255                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19256                for (int i = 0;
19257                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19258                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19259                                || procState > ActivityManager.PROCESS_STATE_TOP);
19260                        i++) {
19261                    // XXX should compute this based on the max of
19262                    // all connected clients.
19263                    ConnectionRecord cr = clist.get(i);
19264                    if (cr.binding.client == app) {
19265                        // Binding to ourself is not interesting.
19266                        continue;
19267                    }
19268                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19269                        app.whitelistManager = true;
19270                    }
19271
19272                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19273                        ProcessRecord client = cr.binding.client;
19274                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19275                                TOP_APP, doingAll, now);
19276                        int clientProcState = client.curProcState;
19277                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19278                            // If the other app is cached for any reason, for purposes here
19279                            // we are going to consider it empty.  The specific cached state
19280                            // doesn't propagate except under certain conditions.
19281                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19282                        }
19283                        String adjType = null;
19284                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19285                            // Not doing bind OOM management, so treat
19286                            // this guy more like a started service.
19287                            if (app.hasShownUi && app != mHomeProcess) {
19288                                // If this process has shown some UI, let it immediately
19289                                // go to the LRU list because it may be pretty heavy with
19290                                // UI stuff.  We'll tag it with a label just to help
19291                                // debug and understand what is going on.
19292                                if (adj > clientAdj) {
19293                                    adjType = "cch-bound-ui-services";
19294                                }
19295                                app.cached = false;
19296                                clientAdj = adj;
19297                                clientProcState = procState;
19298                            } else {
19299                                if (now >= (s.lastActivity
19300                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19301                                    // This service has not seen activity within
19302                                    // recent memory, so allow it to drop to the
19303                                    // LRU list if there is no other reason to keep
19304                                    // it around.  We'll also tag it with a label just
19305                                    // to help debug and undertand what is going on.
19306                                    if (adj > clientAdj) {
19307                                        adjType = "cch-bound-services";
19308                                    }
19309                                    clientAdj = adj;
19310                                }
19311                            }
19312                        }
19313                        if (adj > clientAdj) {
19314                            // If this process has recently shown UI, and
19315                            // the process that is binding to it is less
19316                            // important than being visible, then we don't
19317                            // care about the binding as much as we care
19318                            // about letting this process get into the LRU
19319                            // list to be killed and restarted if needed for
19320                            // memory.
19321                            if (app.hasShownUi && app != mHomeProcess
19322                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19323                                adjType = "cch-bound-ui-services";
19324                            } else {
19325                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19326                                        |Context.BIND_IMPORTANT)) != 0) {
19327                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19328                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19329                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19330                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19331                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19332                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19333                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19334                                    adj = clientAdj;
19335                                } else {
19336                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19337                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19338                                    }
19339                                }
19340                                if (!client.cached) {
19341                                    app.cached = false;
19342                                }
19343                                adjType = "service";
19344                            }
19345                        }
19346                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19347                            // This will treat important bound services identically to
19348                            // the top app, which may behave differently than generic
19349                            // foreground work.
19350                            if (client.curSchedGroup > schedGroup) {
19351                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19352                                    schedGroup = client.curSchedGroup;
19353                                } else {
19354                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19355                                }
19356                            }
19357                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19358                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19359                                    // Special handling of clients who are in the top state.
19360                                    // We *may* want to consider this process to be in the
19361                                    // top state as well, but only if there is not another
19362                                    // reason for it to be running.  Being on the top is a
19363                                    // special state, meaning you are specifically running
19364                                    // for the current top app.  If the process is already
19365                                    // running in the background for some other reason, it
19366                                    // is more important to continue considering it to be
19367                                    // in the background state.
19368                                    mayBeTop = true;
19369                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19370                                } else {
19371                                    // Special handling for above-top states (persistent
19372                                    // processes).  These should not bring the current process
19373                                    // into the top state, since they are not on top.  Instead
19374                                    // give them the best state after that.
19375                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19376                                        clientProcState =
19377                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19378                                    } else if (mWakefulness
19379                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19380                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19381                                                    != 0) {
19382                                        clientProcState =
19383                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19384                                    } else {
19385                                        clientProcState =
19386                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19387                                    }
19388                                }
19389                            }
19390                        } else {
19391                            if (clientProcState <
19392                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19393                                clientProcState =
19394                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19395                            }
19396                        }
19397                        if (procState > clientProcState) {
19398                            procState = clientProcState;
19399                        }
19400                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19401                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19402                            app.pendingUiClean = true;
19403                        }
19404                        if (adjType != null) {
19405                            app.adjType = adjType;
19406                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19407                                    .REASON_SERVICE_IN_USE;
19408                            app.adjSource = cr.binding.client;
19409                            app.adjSourceProcState = clientProcState;
19410                            app.adjTarget = s.name;
19411                        }
19412                    }
19413                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19414                        app.treatLikeActivity = true;
19415                    }
19416                    final ActivityRecord a = cr.activity;
19417                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19418                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19419                            (a.visible || a.state == ActivityState.RESUMED ||
19420                             a.state == ActivityState.PAUSING)) {
19421                            adj = ProcessList.FOREGROUND_APP_ADJ;
19422                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19423                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19424                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19425                                } else {
19426                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19427                                }
19428                            }
19429                            app.cached = false;
19430                            app.adjType = "service";
19431                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19432                                    .REASON_SERVICE_IN_USE;
19433                            app.adjSource = a;
19434                            app.adjSourceProcState = procState;
19435                            app.adjTarget = s.name;
19436                        }
19437                    }
19438                }
19439            }
19440        }
19441
19442        for (int provi = app.pubProviders.size()-1;
19443                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19444                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19445                        || procState > ActivityManager.PROCESS_STATE_TOP);
19446                provi--) {
19447            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19448            for (int i = cpr.connections.size()-1;
19449                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19450                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19451                            || procState > ActivityManager.PROCESS_STATE_TOP);
19452                    i--) {
19453                ContentProviderConnection conn = cpr.connections.get(i);
19454                ProcessRecord client = conn.client;
19455                if (client == app) {
19456                    // Being our own client is not interesting.
19457                    continue;
19458                }
19459                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19460                int clientProcState = client.curProcState;
19461                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19462                    // If the other app is cached for any reason, for purposes here
19463                    // we are going to consider it empty.
19464                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19465                }
19466                if (adj > clientAdj) {
19467                    if (app.hasShownUi && app != mHomeProcess
19468                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19469                        app.adjType = "cch-ui-provider";
19470                    } else {
19471                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19472                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19473                        app.adjType = "provider";
19474                    }
19475                    app.cached &= client.cached;
19476                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19477                            .REASON_PROVIDER_IN_USE;
19478                    app.adjSource = client;
19479                    app.adjSourceProcState = clientProcState;
19480                    app.adjTarget = cpr.name;
19481                }
19482                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19483                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19484                        // Special handling of clients who are in the top state.
19485                        // We *may* want to consider this process to be in the
19486                        // top state as well, but only if there is not another
19487                        // reason for it to be running.  Being on the top is a
19488                        // special state, meaning you are specifically running
19489                        // for the current top app.  If the process is already
19490                        // running in the background for some other reason, it
19491                        // is more important to continue considering it to be
19492                        // in the background state.
19493                        mayBeTop = true;
19494                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19495                    } else {
19496                        // Special handling for above-top states (persistent
19497                        // processes).  These should not bring the current process
19498                        // into the top state, since they are not on top.  Instead
19499                        // give them the best state after that.
19500                        clientProcState =
19501                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19502                    }
19503                }
19504                if (procState > clientProcState) {
19505                    procState = clientProcState;
19506                }
19507                if (client.curSchedGroup > schedGroup) {
19508                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19509                }
19510            }
19511            // If the provider has external (non-framework) process
19512            // dependencies, ensure that its adjustment is at least
19513            // FOREGROUND_APP_ADJ.
19514            if (cpr.hasExternalProcessHandles()) {
19515                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19516                    adj = ProcessList.FOREGROUND_APP_ADJ;
19517                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19518                    app.cached = false;
19519                    app.adjType = "provider";
19520                    app.adjTarget = cpr.name;
19521                }
19522                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19523                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19524                }
19525            }
19526        }
19527
19528        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19529            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19530                adj = ProcessList.PREVIOUS_APP_ADJ;
19531                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19532                app.cached = false;
19533                app.adjType = "provider";
19534            }
19535            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19536                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19537            }
19538        }
19539
19540        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19541            // A client of one of our services or providers is in the top state.  We
19542            // *may* want to be in the top state, but not if we are already running in
19543            // the background for some other reason.  For the decision here, we are going
19544            // to pick out a few specific states that we want to remain in when a client
19545            // is top (states that tend to be longer-term) and otherwise allow it to go
19546            // to the top state.
19547            switch (procState) {
19548                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19549                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19550                case ActivityManager.PROCESS_STATE_SERVICE:
19551                    // These all are longer-term states, so pull them up to the top
19552                    // of the background states, but not all the way to the top state.
19553                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19554                    break;
19555                default:
19556                    // Otherwise, top is a better choice, so take it.
19557                    procState = ActivityManager.PROCESS_STATE_TOP;
19558                    break;
19559            }
19560        }
19561
19562        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19563            if (app.hasClientActivities) {
19564                // This is a cached process, but with client activities.  Mark it so.
19565                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19566                app.adjType = "cch-client-act";
19567            } else if (app.treatLikeActivity) {
19568                // This is a cached process, but somebody wants us to treat it like it has
19569                // an activity, okay!
19570                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19571                app.adjType = "cch-as-act";
19572            }
19573        }
19574
19575        if (adj == ProcessList.SERVICE_ADJ) {
19576            if (doingAll) {
19577                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19578                mNewNumServiceProcs++;
19579                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19580                if (!app.serviceb) {
19581                    // This service isn't far enough down on the LRU list to
19582                    // normally be a B service, but if we are low on RAM and it
19583                    // is large we want to force it down since we would prefer to
19584                    // keep launcher over it.
19585                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19586                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19587                        app.serviceHighRam = true;
19588                        app.serviceb = true;
19589                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19590                    } else {
19591                        mNewNumAServiceProcs++;
19592                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19593                    }
19594                } else {
19595                    app.serviceHighRam = false;
19596                }
19597            }
19598            if (app.serviceb) {
19599                adj = ProcessList.SERVICE_B_ADJ;
19600            }
19601        }
19602
19603        app.curRawAdj = adj;
19604
19605        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19606        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19607        if (adj > app.maxAdj) {
19608            adj = app.maxAdj;
19609            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19610                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19611            }
19612        }
19613
19614        // Do final modification to adj.  Everything we do between here and applying
19615        // the final setAdj must be done in this function, because we will also use
19616        // it when computing the final cached adj later.  Note that we don't need to
19617        // worry about this for max adj above, since max adj will always be used to
19618        // keep it out of the cached vaues.
19619        app.curAdj = app.modifyRawOomAdj(adj);
19620        app.curSchedGroup = schedGroup;
19621        app.curProcState = procState;
19622        app.foregroundActivities = foregroundActivities;
19623
19624        return app.curRawAdj;
19625    }
19626
19627    /**
19628     * Record new PSS sample for a process.
19629     */
19630    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19631            long now) {
19632        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19633                swapPss * 1024);
19634        proc.lastPssTime = now;
19635        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19636        if (DEBUG_PSS) Slog.d(TAG_PSS,
19637                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19638                + " state=" + ProcessList.makeProcStateString(procState));
19639        if (proc.initialIdlePss == 0) {
19640            proc.initialIdlePss = pss;
19641        }
19642        proc.lastPss = pss;
19643        proc.lastSwapPss = swapPss;
19644        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19645            proc.lastCachedPss = pss;
19646            proc.lastCachedSwapPss = swapPss;
19647        }
19648
19649        final SparseArray<Pair<Long, String>> watchUids
19650                = mMemWatchProcesses.getMap().get(proc.processName);
19651        Long check = null;
19652        if (watchUids != null) {
19653            Pair<Long, String> val = watchUids.get(proc.uid);
19654            if (val == null) {
19655                val = watchUids.get(0);
19656            }
19657            if (val != null) {
19658                check = val.first;
19659            }
19660        }
19661        if (check != null) {
19662            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19663                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19664                if (!isDebuggable) {
19665                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19666                        isDebuggable = true;
19667                    }
19668                }
19669                if (isDebuggable) {
19670                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19671                    final ProcessRecord myProc = proc;
19672                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19673                    mMemWatchDumpProcName = proc.processName;
19674                    mMemWatchDumpFile = heapdumpFile.toString();
19675                    mMemWatchDumpPid = proc.pid;
19676                    mMemWatchDumpUid = proc.uid;
19677                    BackgroundThread.getHandler().post(new Runnable() {
19678                        @Override
19679                        public void run() {
19680                            revokeUriPermission(ActivityThread.currentActivityThread()
19681                                            .getApplicationThread(),
19682                                    DumpHeapActivity.JAVA_URI,
19683                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19684                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19685                                    UserHandle.myUserId());
19686                            ParcelFileDescriptor fd = null;
19687                            try {
19688                                heapdumpFile.delete();
19689                                fd = ParcelFileDescriptor.open(heapdumpFile,
19690                                        ParcelFileDescriptor.MODE_CREATE |
19691                                                ParcelFileDescriptor.MODE_TRUNCATE |
19692                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19693                                                ParcelFileDescriptor.MODE_APPEND);
19694                                IApplicationThread thread = myProc.thread;
19695                                if (thread != null) {
19696                                    try {
19697                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19698                                                "Requesting dump heap from "
19699                                                + myProc + " to " + heapdumpFile);
19700                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19701                                    } catch (RemoteException e) {
19702                                    }
19703                                }
19704                            } catch (FileNotFoundException e) {
19705                                e.printStackTrace();
19706                            } finally {
19707                                if (fd != null) {
19708                                    try {
19709                                        fd.close();
19710                                    } catch (IOException e) {
19711                                    }
19712                                }
19713                            }
19714                        }
19715                    });
19716                } else {
19717                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19718                            + ", but debugging not enabled");
19719                }
19720            }
19721        }
19722    }
19723
19724    /**
19725     * Schedule PSS collection of a process.
19726     */
19727    void requestPssLocked(ProcessRecord proc, int procState) {
19728        if (mPendingPssProcesses.contains(proc)) {
19729            return;
19730        }
19731        if (mPendingPssProcesses.size() == 0) {
19732            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19733        }
19734        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19735        proc.pssProcState = procState;
19736        mPendingPssProcesses.add(proc);
19737    }
19738
19739    /**
19740     * Schedule PSS collection of all processes.
19741     */
19742    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19743        if (!always) {
19744            if (now < (mLastFullPssTime +
19745                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19746                return;
19747            }
19748        }
19749        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19750        mLastFullPssTime = now;
19751        mFullPssPending = true;
19752        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19753        mPendingPssProcesses.clear();
19754        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19755            ProcessRecord app = mLruProcesses.get(i);
19756            if (app.thread == null
19757                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19758                continue;
19759            }
19760            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19761                app.pssProcState = app.setProcState;
19762                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19763                        mTestPssMode, isSleepingLocked(), now);
19764                mPendingPssProcesses.add(app);
19765            }
19766        }
19767        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19768    }
19769
19770    public void setTestPssMode(boolean enabled) {
19771        synchronized (this) {
19772            mTestPssMode = enabled;
19773            if (enabled) {
19774                // Whenever we enable the mode, we want to take a snapshot all of current
19775                // process mem use.
19776                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19777            }
19778        }
19779    }
19780
19781    /**
19782     * Ask a given process to GC right now.
19783     */
19784    final void performAppGcLocked(ProcessRecord app) {
19785        try {
19786            app.lastRequestedGc = SystemClock.uptimeMillis();
19787            if (app.thread != null) {
19788                if (app.reportLowMemory) {
19789                    app.reportLowMemory = false;
19790                    app.thread.scheduleLowMemory();
19791                } else {
19792                    app.thread.processInBackground();
19793                }
19794            }
19795        } catch (Exception e) {
19796            // whatever.
19797        }
19798    }
19799
19800    /**
19801     * Returns true if things are idle enough to perform GCs.
19802     */
19803    private final boolean canGcNowLocked() {
19804        boolean processingBroadcasts = false;
19805        for (BroadcastQueue q : mBroadcastQueues) {
19806            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19807                processingBroadcasts = true;
19808            }
19809        }
19810        return !processingBroadcasts
19811                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19812    }
19813
19814    /**
19815     * Perform GCs on all processes that are waiting for it, but only
19816     * if things are idle.
19817     */
19818    final void performAppGcsLocked() {
19819        final int N = mProcessesToGc.size();
19820        if (N <= 0) {
19821            return;
19822        }
19823        if (canGcNowLocked()) {
19824            while (mProcessesToGc.size() > 0) {
19825                ProcessRecord proc = mProcessesToGc.remove(0);
19826                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19827                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19828                            <= SystemClock.uptimeMillis()) {
19829                        // To avoid spamming the system, we will GC processes one
19830                        // at a time, waiting a few seconds between each.
19831                        performAppGcLocked(proc);
19832                        scheduleAppGcsLocked();
19833                        return;
19834                    } else {
19835                        // It hasn't been long enough since we last GCed this
19836                        // process...  put it in the list to wait for its time.
19837                        addProcessToGcListLocked(proc);
19838                        break;
19839                    }
19840                }
19841            }
19842
19843            scheduleAppGcsLocked();
19844        }
19845    }
19846
19847    /**
19848     * If all looks good, perform GCs on all processes waiting for them.
19849     */
19850    final void performAppGcsIfAppropriateLocked() {
19851        if (canGcNowLocked()) {
19852            performAppGcsLocked();
19853            return;
19854        }
19855        // Still not idle, wait some more.
19856        scheduleAppGcsLocked();
19857    }
19858
19859    /**
19860     * Schedule the execution of all pending app GCs.
19861     */
19862    final void scheduleAppGcsLocked() {
19863        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19864
19865        if (mProcessesToGc.size() > 0) {
19866            // Schedule a GC for the time to the next process.
19867            ProcessRecord proc = mProcessesToGc.get(0);
19868            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19869
19870            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19871            long now = SystemClock.uptimeMillis();
19872            if (when < (now+GC_TIMEOUT)) {
19873                when = now + GC_TIMEOUT;
19874            }
19875            mHandler.sendMessageAtTime(msg, when);
19876        }
19877    }
19878
19879    /**
19880     * Add a process to the array of processes waiting to be GCed.  Keeps the
19881     * list in sorted order by the last GC time.  The process can't already be
19882     * on the list.
19883     */
19884    final void addProcessToGcListLocked(ProcessRecord proc) {
19885        boolean added = false;
19886        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19887            if (mProcessesToGc.get(i).lastRequestedGc <
19888                    proc.lastRequestedGc) {
19889                added = true;
19890                mProcessesToGc.add(i+1, proc);
19891                break;
19892            }
19893        }
19894        if (!added) {
19895            mProcessesToGc.add(0, proc);
19896        }
19897    }
19898
19899    /**
19900     * Set up to ask a process to GC itself.  This will either do it
19901     * immediately, or put it on the list of processes to gc the next
19902     * time things are idle.
19903     */
19904    final void scheduleAppGcLocked(ProcessRecord app) {
19905        long now = SystemClock.uptimeMillis();
19906        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19907            return;
19908        }
19909        if (!mProcessesToGc.contains(app)) {
19910            addProcessToGcListLocked(app);
19911            scheduleAppGcsLocked();
19912        }
19913    }
19914
19915    final void checkExcessivePowerUsageLocked(boolean doKills) {
19916        updateCpuStatsNow();
19917
19918        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19919        boolean doWakeKills = doKills;
19920        boolean doCpuKills = doKills;
19921        if (mLastPowerCheckRealtime == 0) {
19922            doWakeKills = false;
19923        }
19924        if (mLastPowerCheckUptime == 0) {
19925            doCpuKills = false;
19926        }
19927        if (stats.isScreenOn()) {
19928            doWakeKills = false;
19929        }
19930        final long curRealtime = SystemClock.elapsedRealtime();
19931        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19932        final long curUptime = SystemClock.uptimeMillis();
19933        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19934        mLastPowerCheckRealtime = curRealtime;
19935        mLastPowerCheckUptime = curUptime;
19936        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19937            doWakeKills = false;
19938        }
19939        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19940            doCpuKills = false;
19941        }
19942        int i = mLruProcesses.size();
19943        while (i > 0) {
19944            i--;
19945            ProcessRecord app = mLruProcesses.get(i);
19946            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19947                long wtime;
19948                synchronized (stats) {
19949                    wtime = stats.getProcessWakeTime(app.info.uid,
19950                            app.pid, curRealtime);
19951                }
19952                long wtimeUsed = wtime - app.lastWakeTime;
19953                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19954                if (DEBUG_POWER) {
19955                    StringBuilder sb = new StringBuilder(128);
19956                    sb.append("Wake for ");
19957                    app.toShortString(sb);
19958                    sb.append(": over ");
19959                    TimeUtils.formatDuration(realtimeSince, sb);
19960                    sb.append(" used ");
19961                    TimeUtils.formatDuration(wtimeUsed, sb);
19962                    sb.append(" (");
19963                    sb.append((wtimeUsed*100)/realtimeSince);
19964                    sb.append("%)");
19965                    Slog.i(TAG_POWER, sb.toString());
19966                    sb.setLength(0);
19967                    sb.append("CPU for ");
19968                    app.toShortString(sb);
19969                    sb.append(": over ");
19970                    TimeUtils.formatDuration(uptimeSince, sb);
19971                    sb.append(" used ");
19972                    TimeUtils.formatDuration(cputimeUsed, sb);
19973                    sb.append(" (");
19974                    sb.append((cputimeUsed*100)/uptimeSince);
19975                    sb.append("%)");
19976                    Slog.i(TAG_POWER, sb.toString());
19977                }
19978                // If a process has held a wake lock for more
19979                // than 50% of the time during this period,
19980                // that sounds bad.  Kill!
19981                if (doWakeKills && realtimeSince > 0
19982                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19983                    synchronized (stats) {
19984                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19985                                realtimeSince, wtimeUsed);
19986                    }
19987                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19988                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19989                } else if (doCpuKills && uptimeSince > 0
19990                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19991                    synchronized (stats) {
19992                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19993                                uptimeSince, cputimeUsed);
19994                    }
19995                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19996                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19997                } else {
19998                    app.lastWakeTime = wtime;
19999                    app.lastCpuTime = app.curCpuTime;
20000                }
20001            }
20002        }
20003    }
20004
20005    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20006            long nowElapsed) {
20007        boolean success = true;
20008
20009        if (app.curRawAdj != app.setRawAdj) {
20010            app.setRawAdj = app.curRawAdj;
20011        }
20012
20013        int changes = 0;
20014
20015        if (app.curAdj != app.setAdj) {
20016            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20017            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20018                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20019                    + app.adjType);
20020            app.setAdj = app.curAdj;
20021        }
20022
20023        if (app.setSchedGroup != app.curSchedGroup) {
20024            app.setSchedGroup = app.curSchedGroup;
20025            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20026                    "Setting sched group of " + app.processName
20027                    + " to " + app.curSchedGroup);
20028            if (app.waitingToKill != null && app.curReceiver == null
20029                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20030                app.kill(app.waitingToKill, true);
20031                success = false;
20032            } else {
20033                int processGroup;
20034                switch (app.curSchedGroup) {
20035                    case ProcessList.SCHED_GROUP_BACKGROUND:
20036                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20037                        break;
20038                    case ProcessList.SCHED_GROUP_TOP_APP:
20039                        processGroup = Process.THREAD_GROUP_TOP_APP;
20040                        break;
20041                    default:
20042                        processGroup = Process.THREAD_GROUP_DEFAULT;
20043                        break;
20044                }
20045                if (true) {
20046                    long oldId = Binder.clearCallingIdentity();
20047                    try {
20048                        Process.setProcessGroup(app.pid, processGroup);
20049                    } catch (Exception e) {
20050                        Slog.w(TAG, "Failed setting process group of " + app.pid
20051                                + " to " + app.curSchedGroup);
20052                        e.printStackTrace();
20053                    } finally {
20054                        Binder.restoreCallingIdentity(oldId);
20055                    }
20056                } else {
20057                    if (app.thread != null) {
20058                        try {
20059                            app.thread.setSchedulingGroup(processGroup);
20060                        } catch (RemoteException e) {
20061                        }
20062                    }
20063                }
20064            }
20065        }
20066        if (app.repForegroundActivities != app.foregroundActivities) {
20067            app.repForegroundActivities = app.foregroundActivities;
20068            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20069        }
20070        if (app.repProcState != app.curProcState) {
20071            app.repProcState = app.curProcState;
20072            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20073            if (app.thread != null) {
20074                try {
20075                    if (false) {
20076                        //RuntimeException h = new RuntimeException("here");
20077                        Slog.i(TAG, "Sending new process state " + app.repProcState
20078                                + " to " + app /*, h*/);
20079                    }
20080                    app.thread.setProcessState(app.repProcState);
20081                } catch (RemoteException e) {
20082                }
20083            }
20084        }
20085        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20086                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20087            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20088                // Experimental code to more aggressively collect pss while
20089                // running test...  the problem is that this tends to collect
20090                // the data right when a process is transitioning between process
20091                // states, which well tend to give noisy data.
20092                long start = SystemClock.uptimeMillis();
20093                long pss = Debug.getPss(app.pid, mTmpLong, null);
20094                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20095                mPendingPssProcesses.remove(app);
20096                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20097                        + " to " + app.curProcState + ": "
20098                        + (SystemClock.uptimeMillis()-start) + "ms");
20099            }
20100            app.lastStateTime = now;
20101            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20102                    mTestPssMode, isSleepingLocked(), now);
20103            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20104                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20105                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20106                    + (app.nextPssTime-now) + ": " + app);
20107        } else {
20108            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20109                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20110                    mTestPssMode)))) {
20111                requestPssLocked(app, app.setProcState);
20112                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20113                        mTestPssMode, isSleepingLocked(), now);
20114            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20115                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20116        }
20117        if (app.setProcState != app.curProcState) {
20118            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20119                    "Proc state change of " + app.processName
20120                            + " to " + app.curProcState);
20121            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20122            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20123            if (setImportant && !curImportant) {
20124                // This app is no longer something we consider important enough to allow to
20125                // use arbitrary amounts of battery power.  Note
20126                // its current wake lock time to later know to kill it if
20127                // it is not behaving well.
20128                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20129                synchronized (stats) {
20130                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20131                            app.pid, nowElapsed);
20132                }
20133                app.lastCpuTime = app.curCpuTime;
20134
20135            }
20136            // Inform UsageStats of important process state change
20137            // Must be called before updating setProcState
20138            maybeUpdateUsageStatsLocked(app, nowElapsed);
20139
20140            app.setProcState = app.curProcState;
20141            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20142                app.notCachedSinceIdle = false;
20143            }
20144            if (!doingAll) {
20145                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20146            } else {
20147                app.procStateChanged = true;
20148            }
20149        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20150                > USAGE_STATS_INTERACTION_INTERVAL) {
20151            // For apps that sit around for a long time in the interactive state, we need
20152            // to report this at least once a day so they don't go idle.
20153            maybeUpdateUsageStatsLocked(app, nowElapsed);
20154        }
20155
20156        if (changes != 0) {
20157            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20158                    "Changes in " + app + ": " + changes);
20159            int i = mPendingProcessChanges.size()-1;
20160            ProcessChangeItem item = null;
20161            while (i >= 0) {
20162                item = mPendingProcessChanges.get(i);
20163                if (item.pid == app.pid) {
20164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20165                            "Re-using existing item: " + item);
20166                    break;
20167                }
20168                i--;
20169            }
20170            if (i < 0) {
20171                // No existing item in pending changes; need a new one.
20172                final int NA = mAvailProcessChanges.size();
20173                if (NA > 0) {
20174                    item = mAvailProcessChanges.remove(NA-1);
20175                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20176                            "Retrieving available item: " + item);
20177                } else {
20178                    item = new ProcessChangeItem();
20179                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20180                            "Allocating new item: " + item);
20181                }
20182                item.changes = 0;
20183                item.pid = app.pid;
20184                item.uid = app.info.uid;
20185                if (mPendingProcessChanges.size() == 0) {
20186                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20187                            "*** Enqueueing dispatch processes changed!");
20188                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20189                }
20190                mPendingProcessChanges.add(item);
20191            }
20192            item.changes |= changes;
20193            item.processState = app.repProcState;
20194            item.foregroundActivities = app.repForegroundActivities;
20195            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20196                    "Item " + Integer.toHexString(System.identityHashCode(item))
20197                    + " " + app.toShortString() + ": changes=" + item.changes
20198                    + " procState=" + item.processState
20199                    + " foreground=" + item.foregroundActivities
20200                    + " type=" + app.adjType + " source=" + app.adjSource
20201                    + " target=" + app.adjTarget);
20202        }
20203
20204        return success;
20205    }
20206
20207    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20208        final UidRecord.ChangeItem pendingChange;
20209        if (uidRec == null || uidRec.pendingChange == null) {
20210            if (mPendingUidChanges.size() == 0) {
20211                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20212                        "*** Enqueueing dispatch uid changed!");
20213                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20214            }
20215            final int NA = mAvailUidChanges.size();
20216            if (NA > 0) {
20217                pendingChange = mAvailUidChanges.remove(NA-1);
20218                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20219                        "Retrieving available item: " + pendingChange);
20220            } else {
20221                pendingChange = new UidRecord.ChangeItem();
20222                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20223                        "Allocating new item: " + pendingChange);
20224            }
20225            if (uidRec != null) {
20226                uidRec.pendingChange = pendingChange;
20227                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20228                    // If this uid is going away, and we haven't yet reported it is gone,
20229                    // then do so now.
20230                    change = UidRecord.CHANGE_GONE_IDLE;
20231                }
20232            } else if (uid < 0) {
20233                throw new IllegalArgumentException("No UidRecord or uid");
20234            }
20235            pendingChange.uidRecord = uidRec;
20236            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20237            mPendingUidChanges.add(pendingChange);
20238        } else {
20239            pendingChange = uidRec.pendingChange;
20240            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20241                change = UidRecord.CHANGE_GONE_IDLE;
20242            }
20243        }
20244        pendingChange.change = change;
20245        pendingChange.processState = uidRec != null
20246                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20247    }
20248
20249    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20250            String authority) {
20251        if (app == null) return;
20252        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20253            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20254            if (userState == null) return;
20255            final long now = SystemClock.elapsedRealtime();
20256            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20257            if (lastReported == null || lastReported < now - 60 * 1000L) {
20258                mUsageStatsService.reportContentProviderUsage(
20259                        authority, providerPkgName, app.userId);
20260                userState.mProviderLastReportedFg.put(authority, now);
20261            }
20262        }
20263    }
20264
20265    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20266        if (DEBUG_USAGE_STATS) {
20267            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20268                    + "] state changes: old = " + app.setProcState + ", new = "
20269                    + app.curProcState);
20270        }
20271        if (mUsageStatsService == null) {
20272            return;
20273        }
20274        boolean isInteraction;
20275        // To avoid some abuse patterns, we are going to be careful about what we consider
20276        // to be an app interaction.  Being the top activity doesn't count while the display
20277        // is sleeping, nor do short foreground services.
20278        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20279            isInteraction = true;
20280            app.fgInteractionTime = 0;
20281        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20282            if (app.fgInteractionTime == 0) {
20283                app.fgInteractionTime = nowElapsed;
20284                isInteraction = false;
20285            } else {
20286                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20287            }
20288        } else {
20289            isInteraction = app.curProcState
20290                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20291            app.fgInteractionTime = 0;
20292        }
20293        if (isInteraction && (!app.reportedInteraction
20294                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20295            app.interactionEventTime = nowElapsed;
20296            String[] packages = app.getPackageList();
20297            if (packages != null) {
20298                for (int i = 0; i < packages.length; i++) {
20299                    mUsageStatsService.reportEvent(packages[i], app.userId,
20300                            UsageEvents.Event.SYSTEM_INTERACTION);
20301                }
20302            }
20303        }
20304        app.reportedInteraction = isInteraction;
20305        if (!isInteraction) {
20306            app.interactionEventTime = 0;
20307        }
20308    }
20309
20310    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20311        if (proc.thread != null) {
20312            if (proc.baseProcessTracker != null) {
20313                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20314            }
20315        }
20316    }
20317
20318    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20319            ProcessRecord TOP_APP, boolean doingAll, long now) {
20320        if (app.thread == null) {
20321            return false;
20322        }
20323
20324        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20325
20326        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20327    }
20328
20329    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20330            boolean oomAdj) {
20331        if (isForeground != proc.foregroundServices) {
20332            proc.foregroundServices = isForeground;
20333            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20334                    proc.info.uid);
20335            if (isForeground) {
20336                if (curProcs == null) {
20337                    curProcs = new ArrayList<ProcessRecord>();
20338                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20339                }
20340                if (!curProcs.contains(proc)) {
20341                    curProcs.add(proc);
20342                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20343                            proc.info.packageName, proc.info.uid);
20344                }
20345            } else {
20346                if (curProcs != null) {
20347                    if (curProcs.remove(proc)) {
20348                        mBatteryStatsService.noteEvent(
20349                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20350                                proc.info.packageName, proc.info.uid);
20351                        if (curProcs.size() <= 0) {
20352                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20353                        }
20354                    }
20355                }
20356            }
20357            if (oomAdj) {
20358                updateOomAdjLocked();
20359            }
20360        }
20361    }
20362
20363    private final ActivityRecord resumedAppLocked() {
20364        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20365        String pkg;
20366        int uid;
20367        if (act != null) {
20368            pkg = act.packageName;
20369            uid = act.info.applicationInfo.uid;
20370        } else {
20371            pkg = null;
20372            uid = -1;
20373        }
20374        // Has the UID or resumed package name changed?
20375        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20376                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20377            if (mCurResumedPackage != null) {
20378                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20379                        mCurResumedPackage, mCurResumedUid);
20380            }
20381            mCurResumedPackage = pkg;
20382            mCurResumedUid = uid;
20383            if (mCurResumedPackage != null) {
20384                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20385                        mCurResumedPackage, mCurResumedUid);
20386            }
20387        }
20388        return act;
20389    }
20390
20391    final boolean updateOomAdjLocked(ProcessRecord app) {
20392        final ActivityRecord TOP_ACT = resumedAppLocked();
20393        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20394        final boolean wasCached = app.cached;
20395
20396        mAdjSeq++;
20397
20398        // This is the desired cached adjusment we want to tell it to use.
20399        // If our app is currently cached, we know it, and that is it.  Otherwise,
20400        // we don't know it yet, and it needs to now be cached we will then
20401        // need to do a complete oom adj.
20402        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20403                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20404        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20405                SystemClock.uptimeMillis());
20406        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20407            // Changed to/from cached state, so apps after it in the LRU
20408            // list may also be changed.
20409            updateOomAdjLocked();
20410        }
20411        return success;
20412    }
20413
20414    final void updateOomAdjLocked() {
20415        final ActivityRecord TOP_ACT = resumedAppLocked();
20416        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20417        final long now = SystemClock.uptimeMillis();
20418        final long nowElapsed = SystemClock.elapsedRealtime();
20419        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20420        final int N = mLruProcesses.size();
20421
20422        if (false) {
20423            RuntimeException e = new RuntimeException();
20424            e.fillInStackTrace();
20425            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20426        }
20427
20428        // Reset state in all uid records.
20429        for (int i=mActiveUids.size()-1; i>=0; i--) {
20430            final UidRecord uidRec = mActiveUids.valueAt(i);
20431            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20432                    "Starting update of " + uidRec);
20433            uidRec.reset();
20434        }
20435
20436        mStackSupervisor.rankTaskLayersIfNeeded();
20437
20438        mAdjSeq++;
20439        mNewNumServiceProcs = 0;
20440        mNewNumAServiceProcs = 0;
20441
20442        final int emptyProcessLimit;
20443        final int cachedProcessLimit;
20444        if (mProcessLimit <= 0) {
20445            emptyProcessLimit = cachedProcessLimit = 0;
20446        } else if (mProcessLimit == 1) {
20447            emptyProcessLimit = 1;
20448            cachedProcessLimit = 0;
20449        } else {
20450            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20451            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20452        }
20453
20454        // Let's determine how many processes we have running vs.
20455        // how many slots we have for background processes; we may want
20456        // to put multiple processes in a slot of there are enough of
20457        // them.
20458        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20459                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20460        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20461        if (numEmptyProcs > cachedProcessLimit) {
20462            // If there are more empty processes than our limit on cached
20463            // processes, then use the cached process limit for the factor.
20464            // This ensures that the really old empty processes get pushed
20465            // down to the bottom, so if we are running low on memory we will
20466            // have a better chance at keeping around more cached processes
20467            // instead of a gazillion empty processes.
20468            numEmptyProcs = cachedProcessLimit;
20469        }
20470        int emptyFactor = numEmptyProcs/numSlots;
20471        if (emptyFactor < 1) emptyFactor = 1;
20472        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20473        if (cachedFactor < 1) cachedFactor = 1;
20474        int stepCached = 0;
20475        int stepEmpty = 0;
20476        int numCached = 0;
20477        int numEmpty = 0;
20478        int numTrimming = 0;
20479
20480        mNumNonCachedProcs = 0;
20481        mNumCachedHiddenProcs = 0;
20482
20483        // First update the OOM adjustment for each of the
20484        // application processes based on their current state.
20485        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20486        int nextCachedAdj = curCachedAdj+1;
20487        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20488        int nextEmptyAdj = curEmptyAdj+2;
20489        for (int i=N-1; i>=0; i--) {
20490            ProcessRecord app = mLruProcesses.get(i);
20491            if (!app.killedByAm && app.thread != null) {
20492                app.procStateChanged = false;
20493                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20494
20495                // If we haven't yet assigned the final cached adj
20496                // to the process, do that now.
20497                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20498                    switch (app.curProcState) {
20499                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20500                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20501                            // This process is a cached process holding activities...
20502                            // assign it the next cached value for that type, and then
20503                            // step that cached level.
20504                            app.curRawAdj = curCachedAdj;
20505                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20506                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20507                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20508                                    + ")");
20509                            if (curCachedAdj != nextCachedAdj) {
20510                                stepCached++;
20511                                if (stepCached >= cachedFactor) {
20512                                    stepCached = 0;
20513                                    curCachedAdj = nextCachedAdj;
20514                                    nextCachedAdj += 2;
20515                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20516                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20517                                    }
20518                                }
20519                            }
20520                            break;
20521                        default:
20522                            // For everything else, assign next empty cached process
20523                            // level and bump that up.  Note that this means that
20524                            // long-running services that have dropped down to the
20525                            // cached level will be treated as empty (since their process
20526                            // state is still as a service), which is what we want.
20527                            app.curRawAdj = curEmptyAdj;
20528                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20529                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20530                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20531                                    + ")");
20532                            if (curEmptyAdj != nextEmptyAdj) {
20533                                stepEmpty++;
20534                                if (stepEmpty >= emptyFactor) {
20535                                    stepEmpty = 0;
20536                                    curEmptyAdj = nextEmptyAdj;
20537                                    nextEmptyAdj += 2;
20538                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20539                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20540                                    }
20541                                }
20542                            }
20543                            break;
20544                    }
20545                }
20546
20547                applyOomAdjLocked(app, true, now, nowElapsed);
20548
20549                // Count the number of process types.
20550                switch (app.curProcState) {
20551                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20552                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20553                        mNumCachedHiddenProcs++;
20554                        numCached++;
20555                        if (numCached > cachedProcessLimit) {
20556                            app.kill("cached #" + numCached, true);
20557                        }
20558                        break;
20559                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20560                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20561                                && app.lastActivityTime < oldTime) {
20562                            app.kill("empty for "
20563                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20564                                    / 1000) + "s", true);
20565                        } else {
20566                            numEmpty++;
20567                            if (numEmpty > emptyProcessLimit) {
20568                                app.kill("empty #" + numEmpty, true);
20569                            }
20570                        }
20571                        break;
20572                    default:
20573                        mNumNonCachedProcs++;
20574                        break;
20575                }
20576
20577                if (app.isolated && app.services.size() <= 0) {
20578                    // If this is an isolated process, and there are no
20579                    // services running in it, then the process is no longer
20580                    // needed.  We agressively kill these because we can by
20581                    // definition not re-use the same process again, and it is
20582                    // good to avoid having whatever code was running in them
20583                    // left sitting around after no longer needed.
20584                    app.kill("isolated not needed", true);
20585                } else {
20586                    // Keeping this process, update its uid.
20587                    final UidRecord uidRec = app.uidRecord;
20588                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20589                        uidRec.curProcState = app.curProcState;
20590                    }
20591                }
20592
20593                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20594                        && !app.killedByAm) {
20595                    numTrimming++;
20596                }
20597            }
20598        }
20599
20600        mNumServiceProcs = mNewNumServiceProcs;
20601
20602        // Now determine the memory trimming level of background processes.
20603        // Unfortunately we need to start at the back of the list to do this
20604        // properly.  We only do this if the number of background apps we
20605        // are managing to keep around is less than half the maximum we desire;
20606        // if we are keeping a good number around, we'll let them use whatever
20607        // memory they want.
20608        final int numCachedAndEmpty = numCached + numEmpty;
20609        int memFactor;
20610        if (numCached <= ProcessList.TRIM_CACHED_APPS
20611                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20612            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20613                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20614            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20615                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20616            } else {
20617                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20618            }
20619        } else {
20620            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20621        }
20622        // We always allow the memory level to go up (better).  We only allow it to go
20623        // down if we are in a state where that is allowed, *and* the total number of processes
20624        // has gone down since last time.
20625        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20626                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20627                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20628        if (memFactor > mLastMemoryLevel) {
20629            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20630                memFactor = mLastMemoryLevel;
20631                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20632            }
20633        }
20634        if (memFactor != mLastMemoryLevel) {
20635            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20636        }
20637        mLastMemoryLevel = memFactor;
20638        mLastNumProcesses = mLruProcesses.size();
20639        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20640        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20641        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20642            if (mLowRamStartTime == 0) {
20643                mLowRamStartTime = now;
20644            }
20645            int step = 0;
20646            int fgTrimLevel;
20647            switch (memFactor) {
20648                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20649                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20650                    break;
20651                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20652                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20653                    break;
20654                default:
20655                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20656                    break;
20657            }
20658            int factor = numTrimming/3;
20659            int minFactor = 2;
20660            if (mHomeProcess != null) minFactor++;
20661            if (mPreviousProcess != null) minFactor++;
20662            if (factor < minFactor) factor = minFactor;
20663            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20664            for (int i=N-1; i>=0; i--) {
20665                ProcessRecord app = mLruProcesses.get(i);
20666                if (allChanged || app.procStateChanged) {
20667                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20668                    app.procStateChanged = false;
20669                }
20670                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20671                        && !app.killedByAm) {
20672                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20673                        try {
20674                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20675                                    "Trimming memory of " + app.processName + " to " + curLevel);
20676                            app.thread.scheduleTrimMemory(curLevel);
20677                        } catch (RemoteException e) {
20678                        }
20679                        if (false) {
20680                            // For now we won't do this; our memory trimming seems
20681                            // to be good enough at this point that destroying
20682                            // activities causes more harm than good.
20683                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20684                                    && app != mHomeProcess && app != mPreviousProcess) {
20685                                // Need to do this on its own message because the stack may not
20686                                // be in a consistent state at this point.
20687                                // For these apps we will also finish their activities
20688                                // to help them free memory.
20689                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20690                            }
20691                        }
20692                    }
20693                    app.trimMemoryLevel = curLevel;
20694                    step++;
20695                    if (step >= factor) {
20696                        step = 0;
20697                        switch (curLevel) {
20698                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20699                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20700                                break;
20701                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20702                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20703                                break;
20704                        }
20705                    }
20706                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20707                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20708                            && app.thread != null) {
20709                        try {
20710                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20711                                    "Trimming memory of heavy-weight " + app.processName
20712                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20713                            app.thread.scheduleTrimMemory(
20714                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20715                        } catch (RemoteException e) {
20716                        }
20717                    }
20718                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20719                } else {
20720                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20721                            || app.systemNoUi) && app.pendingUiClean) {
20722                        // If this application is now in the background and it
20723                        // had done UI, then give it the special trim level to
20724                        // have it free UI resources.
20725                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20726                        if (app.trimMemoryLevel < level && app.thread != null) {
20727                            try {
20728                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20729                                        "Trimming memory of bg-ui " + app.processName
20730                                        + " to " + level);
20731                                app.thread.scheduleTrimMemory(level);
20732                            } catch (RemoteException e) {
20733                            }
20734                        }
20735                        app.pendingUiClean = false;
20736                    }
20737                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20738                        try {
20739                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20740                                    "Trimming memory of fg " + app.processName
20741                                    + " to " + fgTrimLevel);
20742                            app.thread.scheduleTrimMemory(fgTrimLevel);
20743                        } catch (RemoteException e) {
20744                        }
20745                    }
20746                    app.trimMemoryLevel = fgTrimLevel;
20747                }
20748            }
20749        } else {
20750            if (mLowRamStartTime != 0) {
20751                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20752                mLowRamStartTime = 0;
20753            }
20754            for (int i=N-1; i>=0; i--) {
20755                ProcessRecord app = mLruProcesses.get(i);
20756                if (allChanged || app.procStateChanged) {
20757                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20758                    app.procStateChanged = false;
20759                }
20760                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20761                        || app.systemNoUi) && app.pendingUiClean) {
20762                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20763                            && app.thread != null) {
20764                        try {
20765                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20766                                    "Trimming memory of ui hidden " + app.processName
20767                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20768                            app.thread.scheduleTrimMemory(
20769                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20770                        } catch (RemoteException e) {
20771                        }
20772                    }
20773                    app.pendingUiClean = false;
20774                }
20775                app.trimMemoryLevel = 0;
20776            }
20777        }
20778
20779        if (mAlwaysFinishActivities) {
20780            // Need to do this on its own message because the stack may not
20781            // be in a consistent state at this point.
20782            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20783        }
20784
20785        if (allChanged) {
20786            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20787        }
20788
20789        // Update from any uid changes.
20790        for (int i=mActiveUids.size()-1; i>=0; i--) {
20791            final UidRecord uidRec = mActiveUids.valueAt(i);
20792            int uidChange = UidRecord.CHANGE_PROCSTATE;
20793            if (uidRec.setProcState != uidRec.curProcState) {
20794                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20795                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20796                        + " to " + uidRec.curProcState);
20797                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20798                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20799                        uidRec.lastBackgroundTime = nowElapsed;
20800                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20801                            // Note: the background settle time is in elapsed realtime, while
20802                            // the handler time base is uptime.  All this means is that we may
20803                            // stop background uids later than we had intended, but that only
20804                            // happens because the device was sleeping so we are okay anyway.
20805                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20806                        }
20807                    }
20808                } else {
20809                    if (uidRec.idle) {
20810                        uidChange = UidRecord.CHANGE_ACTIVE;
20811                        uidRec.idle = false;
20812                    }
20813                    uidRec.lastBackgroundTime = 0;
20814                }
20815                uidRec.setProcState = uidRec.curProcState;
20816                enqueueUidChangeLocked(uidRec, -1, uidChange);
20817                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20818            }
20819        }
20820
20821        if (mProcessStats.shouldWriteNowLocked(now)) {
20822            mHandler.post(new Runnable() {
20823                @Override public void run() {
20824                    synchronized (ActivityManagerService.this) {
20825                        mProcessStats.writeStateAsyncLocked();
20826                    }
20827                }
20828            });
20829        }
20830
20831        if (DEBUG_OOM_ADJ) {
20832            final long duration = SystemClock.uptimeMillis() - now;
20833            if (false) {
20834                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20835                        new RuntimeException("here").fillInStackTrace());
20836            } else {
20837                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20838            }
20839        }
20840    }
20841
20842    final void idleUids() {
20843        synchronized (this) {
20844            final long nowElapsed = SystemClock.elapsedRealtime();
20845            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20846            long nextTime = 0;
20847            for (int i=mActiveUids.size()-1; i>=0; i--) {
20848                final UidRecord uidRec = mActiveUids.valueAt(i);
20849                final long bgTime = uidRec.lastBackgroundTime;
20850                if (bgTime > 0 && !uidRec.idle) {
20851                    if (bgTime <= maxBgTime) {
20852                        uidRec.idle = true;
20853                        doStopUidLocked(uidRec.uid, uidRec);
20854                    } else {
20855                        if (nextTime == 0 || nextTime > bgTime) {
20856                            nextTime = bgTime;
20857                        }
20858                    }
20859                }
20860            }
20861            if (nextTime > 0) {
20862                mHandler.removeMessages(IDLE_UIDS_MSG);
20863                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20864                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20865            }
20866        }
20867    }
20868
20869    final void runInBackgroundDisabled(int uid) {
20870        synchronized (this) {
20871            UidRecord uidRec = mActiveUids.get(uid);
20872            if (uidRec != null) {
20873                // This uid is actually running...  should it be considered background now?
20874                if (uidRec.idle) {
20875                    doStopUidLocked(uidRec.uid, uidRec);
20876                }
20877            } else {
20878                // This uid isn't actually running...  still send a report about it being "stopped".
20879                doStopUidLocked(uid, null);
20880            }
20881        }
20882    }
20883
20884    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20885        mServices.stopInBackgroundLocked(uid);
20886        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20887    }
20888
20889    final void trimApplications() {
20890        synchronized (this) {
20891            int i;
20892
20893            // First remove any unused application processes whose package
20894            // has been removed.
20895            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20896                final ProcessRecord app = mRemovedProcesses.get(i);
20897                if (app.activities.size() == 0
20898                        && app.curReceiver == null && app.services.size() == 0) {
20899                    Slog.i(
20900                        TAG, "Exiting empty application process "
20901                        + app.toShortString() + " ("
20902                        + (app.thread != null ? app.thread.asBinder() : null)
20903                        + ")\n");
20904                    if (app.pid > 0 && app.pid != MY_PID) {
20905                        app.kill("empty", false);
20906                    } else {
20907                        try {
20908                            app.thread.scheduleExit();
20909                        } catch (Exception e) {
20910                            // Ignore exceptions.
20911                        }
20912                    }
20913                    cleanUpApplicationRecordLocked(app, false, true, -1);
20914                    mRemovedProcesses.remove(i);
20915
20916                    if (app.persistent) {
20917                        addAppLocked(app.info, false, null /* ABI override */);
20918                    }
20919                }
20920            }
20921
20922            // Now update the oom adj for all processes.
20923            updateOomAdjLocked();
20924        }
20925    }
20926
20927    /** This method sends the specified signal to each of the persistent apps */
20928    public void signalPersistentProcesses(int sig) throws RemoteException {
20929        if (sig != Process.SIGNAL_USR1) {
20930            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20931        }
20932
20933        synchronized (this) {
20934            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20935                    != PackageManager.PERMISSION_GRANTED) {
20936                throw new SecurityException("Requires permission "
20937                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20938            }
20939
20940            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20941                ProcessRecord r = mLruProcesses.get(i);
20942                if (r.thread != null && r.persistent) {
20943                    Process.sendSignal(r.pid, sig);
20944                }
20945            }
20946        }
20947    }
20948
20949    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20950        if (proc == null || proc == mProfileProc) {
20951            proc = mProfileProc;
20952            profileType = mProfileType;
20953            clearProfilerLocked();
20954        }
20955        if (proc == null) {
20956            return;
20957        }
20958        try {
20959            proc.thread.profilerControl(false, null, profileType);
20960        } catch (RemoteException e) {
20961            throw new IllegalStateException("Process disappeared");
20962        }
20963    }
20964
20965    private void clearProfilerLocked() {
20966        if (mProfileFd != null) {
20967            try {
20968                mProfileFd.close();
20969            } catch (IOException e) {
20970            }
20971        }
20972        mProfileApp = null;
20973        mProfileProc = null;
20974        mProfileFile = null;
20975        mProfileType = 0;
20976        mAutoStopProfiler = false;
20977        mSamplingInterval = 0;
20978    }
20979
20980    public boolean profileControl(String process, int userId, boolean start,
20981            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20982
20983        try {
20984            synchronized (this) {
20985                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20986                // its own permission.
20987                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20988                        != PackageManager.PERMISSION_GRANTED) {
20989                    throw new SecurityException("Requires permission "
20990                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20991                }
20992
20993                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20994                    throw new IllegalArgumentException("null profile info or fd");
20995                }
20996
20997                ProcessRecord proc = null;
20998                if (process != null) {
20999                    proc = findProcessLocked(process, userId, "profileControl");
21000                }
21001
21002                if (start && (proc == null || proc.thread == null)) {
21003                    throw new IllegalArgumentException("Unknown process: " + process);
21004                }
21005
21006                if (start) {
21007                    stopProfilerLocked(null, 0);
21008                    setProfileApp(proc.info, proc.processName, profilerInfo);
21009                    mProfileProc = proc;
21010                    mProfileType = profileType;
21011                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21012                    try {
21013                        fd = fd.dup();
21014                    } catch (IOException e) {
21015                        fd = null;
21016                    }
21017                    profilerInfo.profileFd = fd;
21018                    proc.thread.profilerControl(start, profilerInfo, profileType);
21019                    fd = null;
21020                    mProfileFd = null;
21021                } else {
21022                    stopProfilerLocked(proc, profileType);
21023                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21024                        try {
21025                            profilerInfo.profileFd.close();
21026                        } catch (IOException e) {
21027                        }
21028                    }
21029                }
21030
21031                return true;
21032            }
21033        } catch (RemoteException e) {
21034            throw new IllegalStateException("Process disappeared");
21035        } finally {
21036            if (profilerInfo != null && profilerInfo.profileFd != null) {
21037                try {
21038                    profilerInfo.profileFd.close();
21039                } catch (IOException e) {
21040                }
21041            }
21042        }
21043    }
21044
21045    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21046        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21047                userId, true, ALLOW_FULL_ONLY, callName, null);
21048        ProcessRecord proc = null;
21049        try {
21050            int pid = Integer.parseInt(process);
21051            synchronized (mPidsSelfLocked) {
21052                proc = mPidsSelfLocked.get(pid);
21053            }
21054        } catch (NumberFormatException e) {
21055        }
21056
21057        if (proc == null) {
21058            ArrayMap<String, SparseArray<ProcessRecord>> all
21059                    = mProcessNames.getMap();
21060            SparseArray<ProcessRecord> procs = all.get(process);
21061            if (procs != null && procs.size() > 0) {
21062                proc = procs.valueAt(0);
21063                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21064                    for (int i=1; i<procs.size(); i++) {
21065                        ProcessRecord thisProc = procs.valueAt(i);
21066                        if (thisProc.userId == userId) {
21067                            proc = thisProc;
21068                            break;
21069                        }
21070                    }
21071                }
21072            }
21073        }
21074
21075        return proc;
21076    }
21077
21078    public boolean dumpHeap(String process, int userId, boolean managed,
21079            String path, ParcelFileDescriptor fd) throws RemoteException {
21080
21081        try {
21082            synchronized (this) {
21083                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21084                // its own permission (same as profileControl).
21085                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21086                        != PackageManager.PERMISSION_GRANTED) {
21087                    throw new SecurityException("Requires permission "
21088                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21089                }
21090
21091                if (fd == null) {
21092                    throw new IllegalArgumentException("null fd");
21093                }
21094
21095                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21096                if (proc == null || proc.thread == null) {
21097                    throw new IllegalArgumentException("Unknown process: " + process);
21098                }
21099
21100                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21101                if (!isDebuggable) {
21102                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21103                        throw new SecurityException("Process not debuggable: " + proc);
21104                    }
21105                }
21106
21107                proc.thread.dumpHeap(managed, path, fd);
21108                fd = null;
21109                return true;
21110            }
21111        } catch (RemoteException e) {
21112            throw new IllegalStateException("Process disappeared");
21113        } finally {
21114            if (fd != null) {
21115                try {
21116                    fd.close();
21117                } catch (IOException e) {
21118                }
21119            }
21120        }
21121    }
21122
21123    @Override
21124    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21125            String reportPackage) {
21126        if (processName != null) {
21127            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21128                    "setDumpHeapDebugLimit()");
21129        } else {
21130            synchronized (mPidsSelfLocked) {
21131                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21132                if (proc == null) {
21133                    throw new SecurityException("No process found for calling pid "
21134                            + Binder.getCallingPid());
21135                }
21136                if (!Build.IS_DEBUGGABLE
21137                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21138                    throw new SecurityException("Not running a debuggable build");
21139                }
21140                processName = proc.processName;
21141                uid = proc.uid;
21142                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21143                    throw new SecurityException("Package " + reportPackage + " is not running in "
21144                            + proc);
21145                }
21146            }
21147        }
21148        synchronized (this) {
21149            if (maxMemSize > 0) {
21150                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21151            } else {
21152                if (uid != 0) {
21153                    mMemWatchProcesses.remove(processName, uid);
21154                } else {
21155                    mMemWatchProcesses.getMap().remove(processName);
21156                }
21157            }
21158        }
21159    }
21160
21161    @Override
21162    public void dumpHeapFinished(String path) {
21163        synchronized (this) {
21164            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21165                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21166                        + " does not match last pid " + mMemWatchDumpPid);
21167                return;
21168            }
21169            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21170                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21171                        + " does not match last path " + mMemWatchDumpFile);
21172                return;
21173            }
21174            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21175            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21176        }
21177    }
21178
21179    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21180    public void monitor() {
21181        synchronized (this) { }
21182    }
21183
21184    void onCoreSettingsChange(Bundle settings) {
21185        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21186            ProcessRecord processRecord = mLruProcesses.get(i);
21187            try {
21188                if (processRecord.thread != null) {
21189                    processRecord.thread.setCoreSettings(settings);
21190                }
21191            } catch (RemoteException re) {
21192                /* ignore */
21193            }
21194        }
21195    }
21196
21197    // Multi-user methods
21198
21199    /**
21200     * Start user, if its not already running, but don't bring it to foreground.
21201     */
21202    @Override
21203    public boolean startUserInBackground(final int userId) {
21204        return mUserController.startUser(userId, /* foreground */ false);
21205    }
21206
21207    @Override
21208    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21209        return mUserController.unlockUser(userId, token, secret, listener);
21210    }
21211
21212    @Override
21213    public boolean switchUser(final int targetUserId) {
21214        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21215        UserInfo currentUserInfo;
21216        UserInfo targetUserInfo;
21217        synchronized (this) {
21218            int currentUserId = mUserController.getCurrentUserIdLocked();
21219            currentUserInfo = mUserController.getUserInfo(currentUserId);
21220            targetUserInfo = mUserController.getUserInfo(targetUserId);
21221            if (targetUserInfo == null) {
21222                Slog.w(TAG, "No user info for user #" + targetUserId);
21223                return false;
21224            }
21225            if (!targetUserInfo.supportsSwitchTo()) {
21226                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21227                return false;
21228            }
21229            if (targetUserInfo.isManagedProfile()) {
21230                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21231                return false;
21232            }
21233            mUserController.setTargetUserIdLocked(targetUserId);
21234        }
21235        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21236        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21237        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21238        return true;
21239    }
21240
21241    void scheduleStartProfilesLocked() {
21242        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21243            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21244                    DateUtils.SECOND_IN_MILLIS);
21245        }
21246    }
21247
21248    @Override
21249    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21250        return mUserController.stopUser(userId, force, callback);
21251    }
21252
21253    @Override
21254    public UserInfo getCurrentUser() {
21255        return mUserController.getCurrentUser();
21256    }
21257
21258    @Override
21259    public boolean isUserRunning(int userId, int flags) {
21260        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21261                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21262            String msg = "Permission Denial: isUserRunning() from pid="
21263                    + Binder.getCallingPid()
21264                    + ", uid=" + Binder.getCallingUid()
21265                    + " requires " + INTERACT_ACROSS_USERS;
21266            Slog.w(TAG, msg);
21267            throw new SecurityException(msg);
21268        }
21269        synchronized (this) {
21270            return mUserController.isUserRunningLocked(userId, flags);
21271        }
21272    }
21273
21274    @Override
21275    public int[] getRunningUserIds() {
21276        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21277                != PackageManager.PERMISSION_GRANTED) {
21278            String msg = "Permission Denial: isUserRunning() from pid="
21279                    + Binder.getCallingPid()
21280                    + ", uid=" + Binder.getCallingUid()
21281                    + " requires " + INTERACT_ACROSS_USERS;
21282            Slog.w(TAG, msg);
21283            throw new SecurityException(msg);
21284        }
21285        synchronized (this) {
21286            return mUserController.getStartedUserArrayLocked();
21287        }
21288    }
21289
21290    @Override
21291    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21292        mUserController.registerUserSwitchObserver(observer);
21293    }
21294
21295    @Override
21296    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21297        mUserController.unregisterUserSwitchObserver(observer);
21298    }
21299
21300    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21301        if (info == null) return null;
21302        ApplicationInfo newInfo = new ApplicationInfo(info);
21303        newInfo.initForUser(userId);
21304        return newInfo;
21305    }
21306
21307    public boolean isUserStopped(int userId) {
21308        synchronized (this) {
21309            return mUserController.getStartedUserStateLocked(userId) == null;
21310        }
21311    }
21312
21313    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21314        if (aInfo == null
21315                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21316            return aInfo;
21317        }
21318
21319        ActivityInfo info = new ActivityInfo(aInfo);
21320        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21321        return info;
21322    }
21323
21324    private boolean processSanityChecksLocked(ProcessRecord process) {
21325        if (process == null || process.thread == null) {
21326            return false;
21327        }
21328
21329        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21330        if (!isDebuggable) {
21331            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21332                return false;
21333            }
21334        }
21335
21336        return true;
21337    }
21338
21339    public boolean startBinderTracking() throws RemoteException {
21340        synchronized (this) {
21341            mBinderTransactionTrackingEnabled = true;
21342            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21343            // permission (same as profileControl).
21344            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21345                    != PackageManager.PERMISSION_GRANTED) {
21346                throw new SecurityException("Requires permission "
21347                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21348            }
21349
21350            for (int i = 0; i < mLruProcesses.size(); i++) {
21351                ProcessRecord process = mLruProcesses.get(i);
21352                if (!processSanityChecksLocked(process)) {
21353                    continue;
21354                }
21355                try {
21356                    process.thread.startBinderTracking();
21357                } catch (RemoteException e) {
21358                    Log.v(TAG, "Process disappared");
21359                }
21360            }
21361            return true;
21362        }
21363    }
21364
21365    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21366        try {
21367            synchronized (this) {
21368                mBinderTransactionTrackingEnabled = false;
21369                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21370                // permission (same as profileControl).
21371                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21372                        != PackageManager.PERMISSION_GRANTED) {
21373                    throw new SecurityException("Requires permission "
21374                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21375                }
21376
21377                if (fd == null) {
21378                    throw new IllegalArgumentException("null fd");
21379                }
21380
21381                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21382                pw.println("Binder transaction traces for all processes.\n");
21383                for (ProcessRecord process : mLruProcesses) {
21384                    if (!processSanityChecksLocked(process)) {
21385                        continue;
21386                    }
21387
21388                    pw.println("Traces for process: " + process.processName);
21389                    pw.flush();
21390                    try {
21391                        TransferPipe tp = new TransferPipe();
21392                        try {
21393                            process.thread.stopBinderTrackingAndDump(
21394                                    tp.getWriteFd().getFileDescriptor());
21395                            tp.go(fd.getFileDescriptor());
21396                        } finally {
21397                            tp.kill();
21398                        }
21399                    } catch (IOException e) {
21400                        pw.println("Failure while dumping IPC traces from " + process +
21401                                ".  Exception: " + e);
21402                        pw.flush();
21403                    } catch (RemoteException e) {
21404                        pw.println("Got a RemoteException while dumping IPC traces from " +
21405                                process + ".  Exception: " + e);
21406                        pw.flush();
21407                    }
21408                }
21409                fd = null;
21410                return true;
21411            }
21412        } finally {
21413            if (fd != null) {
21414                try {
21415                    fd.close();
21416                } catch (IOException e) {
21417                }
21418            }
21419        }
21420    }
21421
21422    private final class LocalService extends ActivityManagerInternal {
21423        @Override
21424        public void onWakefulnessChanged(int wakefulness) {
21425            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21426        }
21427
21428        @Override
21429        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21430                String processName, String abiOverride, int uid, Runnable crashHandler) {
21431            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21432                    processName, abiOverride, uid, crashHandler);
21433        }
21434
21435        @Override
21436        public SleepToken acquireSleepToken(String tag) {
21437            Preconditions.checkNotNull(tag);
21438
21439            ComponentName requestedVrService = null;
21440            ComponentName callingVrActivity = null;
21441            int userId = -1;
21442            synchronized (ActivityManagerService.this) {
21443                if (mFocusedActivity != null) {
21444                    requestedVrService = mFocusedActivity.requestedVrComponent;
21445                    callingVrActivity = mFocusedActivity.info.getComponentName();
21446                    userId = mFocusedActivity.userId;
21447                }
21448            }
21449
21450            if (requestedVrService != null) {
21451                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21452            }
21453
21454            synchronized (ActivityManagerService.this) {
21455                SleepTokenImpl token = new SleepTokenImpl(tag);
21456                mSleepTokens.add(token);
21457                updateSleepIfNeededLocked();
21458                return token;
21459            }
21460        }
21461
21462        @Override
21463        public ComponentName getHomeActivityForUser(int userId) {
21464            synchronized (ActivityManagerService.this) {
21465                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21466                return homeActivity == null ? null : homeActivity.realActivity;
21467            }
21468        }
21469
21470        @Override
21471        public void onUserRemoved(int userId) {
21472            synchronized (ActivityManagerService.this) {
21473                ActivityManagerService.this.onUserStoppedLocked(userId);
21474            }
21475        }
21476
21477        @Override
21478        public void onLocalVoiceInteractionStarted(IBinder activity,
21479                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21480            synchronized (ActivityManagerService.this) {
21481                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21482                        voiceSession, voiceInteractor);
21483            }
21484        }
21485
21486        @Override
21487        public void notifyStartingWindowDrawn() {
21488            synchronized (ActivityManagerService.this) {
21489                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21490            }
21491        }
21492
21493        @Override
21494        public void notifyAppTransitionStarting(int reason) {
21495            synchronized (ActivityManagerService.this) {
21496                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21497            }
21498        }
21499
21500        @Override
21501        public void notifyAppTransitionFinished() {
21502            synchronized (ActivityManagerService.this) {
21503                mStackSupervisor.notifyAppTransitionDone();
21504            }
21505        }
21506
21507        @Override
21508        public void notifyAppTransitionCancelled() {
21509            synchronized (ActivityManagerService.this) {
21510                mStackSupervisor.notifyAppTransitionDone();
21511            }
21512        }
21513
21514        @Override
21515        public List<IBinder> getTopVisibleActivities() {
21516            synchronized (ActivityManagerService.this) {
21517                return mStackSupervisor.getTopVisibleActivities();
21518            }
21519        }
21520
21521        @Override
21522        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21523            synchronized (ActivityManagerService.this) {
21524                mStackSupervisor.setDockedStackMinimized(minimized);
21525            }
21526        }
21527
21528        @Override
21529        public void killForegroundAppsForUser(int userHandle) {
21530            synchronized (ActivityManagerService.this) {
21531                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21532                final int NP = mProcessNames.getMap().size();
21533                for (int ip = 0; ip < NP; ip++) {
21534                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21535                    final int NA = apps.size();
21536                    for (int ia = 0; ia < NA; ia++) {
21537                        final ProcessRecord app = apps.valueAt(ia);
21538                        if (app.persistent) {
21539                            // We don't kill persistent processes.
21540                            continue;
21541                        }
21542                        if (app.removed) {
21543                            procs.add(app);
21544                        } else if (app.userId == userHandle && app.foregroundActivities) {
21545                            app.removed = true;
21546                            procs.add(app);
21547                        }
21548                    }
21549                }
21550
21551                final int N = procs.size();
21552                for (int i = 0; i < N; i++) {
21553                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21554                }
21555            }
21556        }
21557
21558        @Override
21559        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21560            if (!(target instanceof PendingIntentRecord)) {
21561                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21562                return;
21563            }
21564            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21565        }
21566    }
21567
21568    private final class SleepTokenImpl extends SleepToken {
21569        private final String mTag;
21570        private final long mAcquireTime;
21571
21572        public SleepTokenImpl(String tag) {
21573            mTag = tag;
21574            mAcquireTime = SystemClock.uptimeMillis();
21575        }
21576
21577        @Override
21578        public void release() {
21579            synchronized (ActivityManagerService.this) {
21580                if (mSleepTokens.remove(this)) {
21581                    updateSleepIfNeededLocked();
21582                }
21583            }
21584        }
21585
21586        @Override
21587        public String toString() {
21588            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21589        }
21590    }
21591
21592    /**
21593     * An implementation of IAppTask, that allows an app to manage its own tasks via
21594     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21595     * only the process that calls getAppTasks() can call the AppTask methods.
21596     */
21597    class AppTaskImpl extends IAppTask.Stub {
21598        private int mTaskId;
21599        private int mCallingUid;
21600
21601        public AppTaskImpl(int taskId, int callingUid) {
21602            mTaskId = taskId;
21603            mCallingUid = callingUid;
21604        }
21605
21606        private void checkCaller() {
21607            if (mCallingUid != Binder.getCallingUid()) {
21608                throw new SecurityException("Caller " + mCallingUid
21609                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21610            }
21611        }
21612
21613        @Override
21614        public void finishAndRemoveTask() {
21615            checkCaller();
21616
21617            synchronized (ActivityManagerService.this) {
21618                long origId = Binder.clearCallingIdentity();
21619                try {
21620                    // We remove the task from recents to preserve backwards
21621                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21622                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21623                    }
21624                } finally {
21625                    Binder.restoreCallingIdentity(origId);
21626                }
21627            }
21628        }
21629
21630        @Override
21631        public ActivityManager.RecentTaskInfo getTaskInfo() {
21632            checkCaller();
21633
21634            synchronized (ActivityManagerService.this) {
21635                long origId = Binder.clearCallingIdentity();
21636                try {
21637                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21638                    if (tr == null) {
21639                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21640                    }
21641                    return createRecentTaskInfoFromTaskRecord(tr);
21642                } finally {
21643                    Binder.restoreCallingIdentity(origId);
21644                }
21645            }
21646        }
21647
21648        @Override
21649        public void moveToFront() {
21650            checkCaller();
21651            // Will bring task to front if it already has a root activity.
21652            final long origId = Binder.clearCallingIdentity();
21653            try {
21654                synchronized (this) {
21655                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21656                }
21657            } finally {
21658                Binder.restoreCallingIdentity(origId);
21659            }
21660        }
21661
21662        @Override
21663        public int startActivity(IBinder whoThread, String callingPackage,
21664                Intent intent, String resolvedType, Bundle bOptions) {
21665            checkCaller();
21666
21667            int callingUser = UserHandle.getCallingUserId();
21668            TaskRecord tr;
21669            IApplicationThread appThread;
21670            synchronized (ActivityManagerService.this) {
21671                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21672                if (tr == null) {
21673                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21674                }
21675                appThread = ApplicationThreadNative.asInterface(whoThread);
21676                if (appThread == null) {
21677                    throw new IllegalArgumentException("Bad app thread " + appThread);
21678                }
21679            }
21680            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21681                    resolvedType, null, null, null, null, 0, 0, null, null,
21682                    null, bOptions, false, callingUser, null, tr);
21683        }
21684
21685        @Override
21686        public void setExcludeFromRecents(boolean exclude) {
21687            checkCaller();
21688
21689            synchronized (ActivityManagerService.this) {
21690                long origId = Binder.clearCallingIdentity();
21691                try {
21692                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21693                    if (tr == null) {
21694                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21695                    }
21696                    Intent intent = tr.getBaseIntent();
21697                    if (exclude) {
21698                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21699                    } else {
21700                        intent.setFlags(intent.getFlags()
21701                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21702                    }
21703                } finally {
21704                    Binder.restoreCallingIdentity(origId);
21705                }
21706            }
21707        }
21708    }
21709
21710    /**
21711     * Kill processes for the user with id userId and that depend on the package named packageName
21712     */
21713    @Override
21714    public void killPackageDependents(String packageName, int userId) {
21715        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21716        if (packageName == null) {
21717            throw new NullPointerException(
21718                    "Cannot kill the dependents of a package without its name.");
21719        }
21720
21721        long callingId = Binder.clearCallingIdentity();
21722        IPackageManager pm = AppGlobals.getPackageManager();
21723        int pkgUid = -1;
21724        try {
21725            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21726        } catch (RemoteException e) {
21727        }
21728        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21729            throw new IllegalArgumentException(
21730                    "Cannot kill dependents of non-existing package " + packageName);
21731        }
21732        try {
21733            synchronized(this) {
21734                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21735                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21736                        "dep: " + packageName);
21737            }
21738        } finally {
21739            Binder.restoreCallingIdentity(callingId);
21740        }
21741    }
21742}
21743